Skip to content
Closed
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
10 changes: 5 additions & 5 deletions src/main/java/de/dafuqs/spectrum/api/recipe/GatedRecipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ public interface GatedRecipe<C extends Inventory> extends Recipe<C> {
boolean isSecret();
Identifier getRequiredAdvancementIdentifier();
Identifier getRecipeTypeUnlockIdentifier();

String getRecipeTypeShortID();

default boolean canPlayerCraft(PlayerEntity playerEntity) {
return AdvancementHelper.hasAdvancement(playerEntity, getRecipeTypeUnlockIdentifier())
&& AdvancementHelper.hasAdvancement(playerEntity, getRequiredAdvancementIdentifier());
}

default Text getSingleUnlockToastString() {
return Text.translatable("spectrum.toast." + getRecipeTypeShortID() + "_recipe_unlocked.title");
}

default Text getMultipleUnlockToastString() {
return Text.translatable("spectrum.toast." + getRecipeTypeShortID() + "_recipes_unlocked.title");
}

default void registerInToastManager(RecipeType<?> recipeType, GatedRecipe<C> gatedRecipe) {
if (FabricLoader.getInstance().getEnvironmentType() != EnvType.SERVER) {
registerInToastManagerClient(recipeType, gatedRecipe);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,12 @@ public static void enchantCenterItem(@NotNull EnchanterBlockEntity enchanterBloc
public static Map<Enchantment, Integer> getHighestEnchantmentsInItemBowls(@NotNull EnchanterBlockEntity enchanterBlockEntity) {
List<ItemStack> bowlStacks = new ArrayList<>();
for (int i = 0; i < 8; i++) {
bowlStacks.add(enchanterBlockEntity.virtualInventoryIncludingBowlStacks.getStack(2 + i));
if (!SpectrumItemTags.isIn(SpectrumItemTags.ENCHANTER_ITEM_BLACKLIST, enchanterBlockEntity.virtualInventoryIncludingBowlStacks.getStack(2 + i).getItem())) {
bowlStacks.add(enchanterBlockEntity.virtualInventoryIncludingBowlStacks.getStack(2 + i));
}
}

return SpectrumEnchantmentHelper.collectHighestEnchantments(bowlStacks);
return SpectrumEnchantmentHelper.collectHighestEnchantments(bowlStacks, SpectrumEnchantmentTags.ENCHANTER_BLACKLIST);
}

public static int getRequiredExperienceToEnchantCenterItem(@NotNull EnchanterBlockEntity enchanterBlockEntity) {
Expand Down
200 changes: 53 additions & 147 deletions src/main/java/de/dafuqs/spectrum/commands/SanityCommand.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void registerDisplays(DisplayRegistry registry) {
registry.registerRecipeFiller(CinderhearthRecipe.class, SpectrumRecipeTypes.CINDERHEARTH, CinderhearthDisplay::new);
registry.registerRecipeFiller(ITitrationBarrelRecipe.class, SpectrumRecipeTypes.TITRATION_BARREL, TitrationBarrelDisplay::new);
registry.registerRecipeFiller(PrimordialFireBurningRecipe.class, SpectrumRecipeTypes.PRIMORDIAL_FIRE_BURNING, PrimordialFireBurningDisplay::new);

NaturesStaffConversionDataLoader.CONVERSIONS.forEach((key, value) -> registry.add(new NaturesStaffConversionsDisplay(EntryStacks.of(key), EntryStacks.of(value.getBlock()), NaturesStaffConversionDataLoader.UNLOCK_IDENTIFIERS.getOrDefault(key, null))));
FreezingIdolBlock.FREEZING_STATE_MAP.forEach((key, value) -> registry.add(new FreezingDisplay(BlockToBlockWithChanceDisplay.blockToEntryStack(key.getBlock()), BlockToBlockWithChanceDisplay.blockToEntryStack(value.getLeft().getBlock()), value.getRight())));
FreezingIdolBlock.FREEZING_MAP.forEach((key, value) -> registry.add(new FreezingDisplay(BlockToBlockWithChanceDisplay.blockToEntryStack(key), BlockToBlockWithChanceDisplay.blockToEntryStack(value.getLeft().getBlock()), value.getRight())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,18 @@ public static void register() {
registerIntegrationPack(CREATE_ID, () -> new CreateCompat());
registerIntegrationPack(FARMERSDELIGHT_ID, () -> new FDCompat());
registerIntegrationPack(GOBBER_ID, () -> new GobberCompat());
registerIntegrationPack(MALUM_ID, () -> new MalumCompat());
registerIntegrationPack(NEEPMEAT_ID, () -> new NEEPMeatCompat());

if (!CONNECTOR_LOADED) {
// Traveler's Backpack for Forge crashes due to Fabric lacking Fluid#getFluidType (a Forge method)
// This cannot be reasonably worked around AFAIK
// ~unilock, 2025

//Malum for Fabric uses Create Porter Lib, Atemps to register enchantments though it create NoSuchField errors
// Needs replacement or hacky workaround
// ~Shibva, 2026
registerIntegrationPack(TRAVELERS_BACKPACK_ID, () -> new TravelersBackpackCompat());
registerIntegrationPack(MALUM_ID, () -> new MalumCompat());
}

for (ModIntegrationPack container : INTEGRATION_PACKS.values()) {
Expand Down
134 changes: 5 additions & 129 deletions src/main/java/de/dafuqs/spectrum/compat/emi/SpectrumEmiPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@

import de.dafuqs.spectrum.*;
import de.dafuqs.spectrum.api.block.*;
import de.dafuqs.spectrum.blocks.fluid.*;
import de.dafuqs.spectrum.blocks.idols.*;
import de.dafuqs.spectrum.compat.*;
import de.dafuqs.spectrum.compat.emi.handlers.*;
import de.dafuqs.spectrum.compat.emi.recipes.*;
import de.dafuqs.spectrum.data_loaders.*;
import de.dafuqs.spectrum.inventories.*;
import de.dafuqs.spectrum.inventories.slots.*;
import de.dafuqs.spectrum.recipe.fluid_converting.*;
import de.dafuqs.spectrum.registries.*;
import dev.emi.emi.api.*;
import dev.emi.emi.api.recipe.*;
import dev.emi.emi.api.stack.*;
import net.fabricmc.loader.api.*;
import net.minecraft.block.*;
import net.minecraft.client.gui.screen.ingame.*;
import net.minecraft.fluid.*;
import net.minecraft.inventory.*;
import net.minecraft.recipe.*;
import net.minecraft.registry.*;
Expand Down Expand Up @@ -154,7 +149,7 @@ public void registerRecipes(EmiRegistry registry) {
return;
}
Identifier id = syntheticId("freezing", key.getBlock()); // The synthetic IDs generated here assume there will never be multiple conversions of the same block with different states
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.FREEZING, id, in, out, SpectrumAdvancements.UNLOCK_IDOLS));
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.FREEZING, id, in, out, SpectrumCommon.locate("unlocks/blocks/idols")));
});
FreezingIdolBlock.FREEZING_MAP.forEach((key, value) -> {
EmiStack in = EmiStack.of(key);
Expand All @@ -163,7 +158,7 @@ public void registerRecipes(EmiRegistry registry) {
return;
}
Identifier id = syntheticId("freezing", key);
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.FREEZING, id, in, out, SpectrumAdvancements.UNLOCK_IDOLS));
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.FREEZING, id, in, out, SpectrumCommon.locate("unlocks/blocks/idols")));
});
FirestarterIdolBlock.BURNING_MAP.forEach((key, value) -> {
EmiStack in = EmiStack.of(key);
Expand All @@ -172,7 +167,7 @@ public void registerRecipes(EmiRegistry registry) {
return;
}
Identifier id = syntheticId("heating", key);
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.HEATING, id, in, out, SpectrumAdvancements.UNLOCK_IDOLS));
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.HEATING, id, in, out, SpectrumCommon.locate("unlocks/blocks/idols")));
});
NaturesStaffConversionDataLoader.CONVERSIONS.forEach((key, value) -> {
EmiStack in = EmiStack.of(key);
Expand All @@ -181,118 +176,8 @@ public void registerRecipes(EmiRegistry registry) {
return;
}
Identifier id = syntheticId("natures_staff", key);
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.NATURES_STAFF, id, in, out, SpectrumAdvancements.UNLOCK_NATURES_STAFF));
registry.addRecipe(new BlockToBlockWithChanceEmiRecipe(SpectrumEmiRecipeCategories.NATURES_STAFF, id, in, out, SpectrumCommon.locate("unlocks/items/natures_staff")));
});

//WorldInteractionRecipe
long amount = SpectrumIntegrationPacks.CONNECTOR_LOADED ? 1_000 : 81_000;
EmiStack water = EmiStack.of(Fluids.WATER, amount);
EmiStack lava = EmiStack.of(Fluids.LAVA, amount);
EmiStack dragonrot = EmiStack.of(SpectrumFluids.DRAGONROT, amount);
EmiStack liquidCrystal = EmiStack.of(SpectrumFluids.LIQUID_CRYSTAL, amount);
EmiStack midnightSolution = EmiStack.of(SpectrumFluids.MIDNIGHT_SOLUTION, amount);
EmiStack mud = EmiStack.of(SpectrumFluids.MUD, amount);
EmiStack waterCatalyst = water.copy().setRemainder(water);
EmiStack lavaCatalyst = lava.copy().setRemainder(lava);
EmiStack dragonrotCatalyst = dragonrot.copy().setRemainder(dragonrot);
EmiStack liquidCrystalCatalyst = liquidCrystal.copy().setRemainder(liquidCrystal);
EmiStack midnightSolutionCatalyst = midnightSolution.copy().setRemainder(midnightSolution);
EmiStack mudCatalyst = mud.copy().setRemainder(mud);
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", SpectrumBlocks.SLUSH))
.leftInput(dragonrotCatalyst)
.rightInput(waterCatalyst, false)
.output(EmiStack.of(SpectrumBlocks.SLUSH))
.requiredAdvancement(DragonrotConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.BLACKSTONE))
.leftInput(dragonrotCatalyst)
.rightInput(lavaCatalyst, false)
.output(EmiStack.of(Blocks.BLACKSTONE))
.requiredAdvancement(DragonrotConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.COARSE_DIRT))
.leftInput(dragonrotCatalyst)
.rightInput(mudCatalyst, false)
.output(EmiStack.of(Blocks.COARSE_DIRT))
.requiredAdvancement(DragonrotConvertingRecipe.UNLOCK_IDENTIFIER)
.requiredAdvancement(MudConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", SpectrumBlocks.ROTTEN_GROUND))
.leftInput(dragonrotCatalyst)
.rightInput(liquidCrystalCatalyst, false)
.output(EmiStack.of(SpectrumBlocks.ROTTEN_GROUND))
.requiredAdvancement(DragonrotConvertingRecipe.UNLOCK_IDENTIFIER)
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", SpectrumBlocks.BLACK_SLUDGE))
.leftInput(dragonrotCatalyst)
.rightInput(midnightSolutionCatalyst, false)
.output(EmiStack.of(SpectrumBlocks.BLACK_SLUDGE))
.requiredAdvancement(DragonrotConvertingRecipe.UNLOCK_IDENTIFIER)
.requiredAdvancement(MidnightSolutionConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", SpectrumBlocks.FROSTBITE_CRYSTAL))
.leftInput(liquidCrystal)
.rightInput(waterCatalyst, false)
.output(EmiStack.of(SpectrumBlocks.FROSTBITE_CRYSTAL))
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.CALCITE))
.leftInput(liquidCrystalCatalyst)
.rightInput(waterCatalyst, false)
.output(EmiStack.of(Blocks.CALCITE))
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", SpectrumBlocks.BLAZING_CRYSTAL))
.leftInput(liquidCrystal)
.rightInput(lavaCatalyst, false)
.output(EmiStack.of(SpectrumBlocks.BLAZING_CRYSTAL))
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.COBBLED_DEEPSLATE))
.leftInput(liquidCrystalCatalyst)
.rightInput(lavaCatalyst, false)
.output(EmiStack.of(Blocks.COBBLED_DEEPSLATE))
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.CLAY))
.leftInput(liquidCrystalCatalyst)
.rightInput(mudCatalyst, false)
.output(EmiStack.of(Blocks.CLAY))
.requiredAdvancement(LiquidCrystalConvertingRecipe.UNLOCK_IDENTIFIER)
.requiredAdvancement(MudConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.TERRACOTTA))
.leftInput(midnightSolutionCatalyst)
.rightInput(lavaCatalyst, false)
.output(EmiStack.of(Blocks.TERRACOTTA))
.requiredAdvancement(MidnightSolutionConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.DIRT))
.leftInput(mudCatalyst)
.rightInput(waterCatalyst, false)
.output(EmiStack.of(Blocks.DIRT))
.requiredAdvancement(MudConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
addRecipeSafe(registry, () -> SpectrumWorldInteractionRecipe.customBuilder()
.id(syntheticId("world/fluid_interaction", Blocks.MUD))
.leftInput(mudCatalyst)
.rightInput(lavaCatalyst, false)
.output(EmiStack.of(Blocks.MUD))
.requiredAdvancement(MudConvertingRecipe.UNLOCK_IDENTIFIER)
.build());
}

public void registerRecipeHandlers(EmiRegistry registry) {
Expand All @@ -313,14 +198,5 @@ public <C extends Inventory, T extends Recipe<C>> void addAll(EmiRegistry regist
registry.addRecipe(constructor.apply(recipe));
}
}

private static void addRecipeSafe(EmiRegistry registry, Supplier<EmiRecipe> supplier) {
try {
registry.addRecipe(supplier.get());
} catch (Throwable e) {
SpectrumCommon.logWarning("Exception thrown when parsing EMI recipe (no ID available)");
SpectrumCommon.logError(e.toString());
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public EnchanterEmiRecipeGated(EmiRecipeCategory category, EnchantmentUpgradeRec
}
inputs.add(EmiStack.of(KnowledgeGemItem.getKnowledgeDropStackWithXP(recipe.getRequiredExperience(), true)));
}

private EnchanterEmiRecipeGated(EmiRecipeCategory category, GatedSpectrumRecipe<?> recipe, Text description, int craftingTime) {
super(category, recipe, 132, 80);
this.craftingTime = craftingTime;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package de.dafuqs.spectrum.compat.emi.recipes;

import de.dafuqs.spectrum.compat.emi.*;
import de.dafuqs.spectrum.recipe.crafting.*;
import dev.emi.emi.api.recipe.*;
import dev.emi.emi.api.render.*;
import dev.emi.emi.api.stack.*;
import dev.emi.emi.api.widget.*;
import net.minecraft.item.*;

public class ShapedGatedCraftingEMIRecipe extends GatedSpectrumEmiRecipe<ShapedGatedCraftingRecipe> {

public ShapedGatedCraftingEMIRecipe(ShapedGatedCraftingRecipe recipe) {
super(VanillaEmiRecipeCategories.CRAFTING, recipe, 118, 54);
}

public boolean canFit(int width, int height) {
if (inputs.size() > 9) {
return false;
}
for (int i = 0; i < inputs.size(); i++) {
int x = i % 3;
int y = i / 3;
if (!inputs.get(i).isEmpty() && (x >= width || y >= height)) {
return false;
}
}
return true;
}

@Override
public void addUnlockedWidgets(WidgetHolder widgets) {
widgets.addTexture(EmiTexture.EMPTY_ARROW, 60, 18);

int sOff = 0;
if (canFit(1, 3)) {
sOff -= 1;
}
if (canFit(3, 1)) {
sOff -= 3;
}
for (int i = 0; i < 9; i++) {
int s = i + sOff;
if (s >= 0 && s < inputs.size()) {
widgets.addSlot(inputs.get(s), i % 3 * 18, i / 3 * 18);
} else {
widgets.addSlot(EmiStack.of(ItemStack.EMPTY), i % 3 * 18, i / 3 * 18);
}
}

widgets.addSlot(outputs.get(0), 92, 14).large(true).recipeContext(this);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package de.dafuqs.spectrum.compat.emi.recipes;

import de.dafuqs.spectrum.compat.emi.*;
import de.dafuqs.spectrum.recipe.crafting.*;
import dev.emi.emi.api.recipe.*;
import dev.emi.emi.api.render.*;
import dev.emi.emi.api.stack.*;
import dev.emi.emi.api.widget.*;
import net.minecraft.item.*;

public class ShapelessGatedCraftingEMIRecipe extends GatedSpectrumEmiRecipe<ShapelessGatedCraftingRecipe> {

public ShapelessGatedCraftingEMIRecipe(ShapelessGatedCraftingRecipe recipe) {
super(VanillaEmiRecipeCategories.CRAFTING, recipe, 118, 54);
}

@Override
public void addUnlockedWidgets(WidgetHolder widgets) {
widgets.addTexture(EmiTexture.EMPTY_ARROW, 60, 18);
widgets.addTexture(EmiTexture.SHAPELESS, 97, 0);

for (int i = 0; i < 9; i++) {
if (i < inputs.size()) {
widgets.addSlot(inputs.get(i), i % 3 * 18, i / 3 * 18);
} else {
widgets.addSlot(EmiStack.of(ItemStack.EMPTY), i % 3 * 18, i / 3 * 18);
}
}

widgets.addSlot(outputs.get(0), 92, 14).large(true).recipeContext(this);
}

}
Loading
Loading