- Fixed Create's JEI plugin not reloading recipes properly
- Reverted an AT that seems to cause issues with compiling in IDEs
- Fixed Contraption disassembly causing inventory contents to be rolled back
- Fixed Crushing Wheels not working correctly
- Items idling on top of Crushing Wheels are no longer prevented from being picked up by players
- Fixed automated compatibility picking up custom recipes from the mod "occultism"
This commit is contained in:
simibubi 2022-03-21 00:29:45 +01:00
parent 939b276c56
commit a8c368f426
15 changed files with 118 additions and 101 deletions

View file

@ -49,6 +49,7 @@ body:
label: Mod Version label: Mod Version
description: The version of the mod you were using when the bug occured description: The version of the mod you were using when the bug occured
options: options:
- "0.4.0f"
- "0.4.0e" - "0.4.0e"
- "0.4.0d" - "0.4.0d"
- "0.4.0c" - "0.4.0c"

View file

@ -4,7 +4,7 @@ org.gradle.jvmargs = -Xmx3G
org.gradle.daemon = false org.gradle.daemon = false
# mod version info # mod version info
mod_version = 0.4e mod_version = 0.4f
minecraft_version = 1.18.1 minecraft_version = 1.18.1
forge_version = 39.1.0 forge_version = 39.1.0

View file

@ -1,8 +1,10 @@
package com.simibubi.create; package com.simibubi.create;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.google.common.collect.ImmutableSet;
import com.simibubi.create.compat.jei.ConversionRecipe; import com.simibubi.create.compat.jei.ConversionRecipe;
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe;
import com.simibubi.create.content.contraptions.components.crusher.CrushingRecipe; import com.simibubi.create.content.contraptions.components.crusher.CrushingRecipe;
@ -134,7 +136,13 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
}); });
} }
public static boolean isManualRecipe(Recipe<?> recipe) { public static final Set<ResourceLocation> RECIPE_DENY_SET =
ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual"));
public static boolean shouldIgnoreInAutomation(Recipe<?> recipe) {
RecipeSerializer<?> serializer = recipe.getSerializer();
if (serializer != null && RECIPE_DENY_SET.contains(serializer.getRegistryName()))
return true;
return recipe.getId() return recipe.getId()
.getPath() .getPath()
.endsWith("_manual_only"); .endsWith("_manual_only");

View file

@ -57,7 +57,7 @@ public class Create {
public static final String ID = "create"; public static final String ID = "create";
public static final String NAME = "Create"; public static final String NAME = "Create";
public static final String VERSION = "0.4e"; public static final String VERSION = "0.4f";
public static final Logger LOGGER = LogManager.getLogger(); public static final Logger LOGGER = LogManager.getLogger();

View file

@ -85,141 +85,152 @@ public class CreateJEI implements IModPlugin {
public IIngredientManager ingredientManager; public IIngredientManager ingredientManager;
private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>(); private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
private final CreateRecipeCategory<?>
private void loadCategories() {
allCategories.clear();
CreateRecipeCategory<?>
milling = register("milling", MillingCategory::new).addTypedRecipes(AllRecipeTypes.MILLING) milling = register("milling", MillingCategory::new).addTypedRecipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get) .catalyst(AllBlocks.MILLSTONE::get)
.build(), .build(),
crushing = register("crushing", CrushingCategory::new).addTypedRecipes(AllRecipeTypes.CRUSHING) crushing = register("crushing", CrushingCategory::new).addTypedRecipes(AllRecipeTypes.CRUSHING)
.addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType) .addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
.catalyst(AllBlocks.CRUSHING_WHEEL::get) .catalyst(AllBlocks.CRUSHING_WHEEL::get)
.build(), .build(),
pressing = register("pressing", PressingCategory::new).addTypedRecipes(AllRecipeTypes.PRESSING) pressing = register("pressing", PressingCategory::new).addTypedRecipes(AllRecipeTypes.PRESSING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.MECHANICAL_PRESS::get)
.build(), .build(),
washing = register("fan_washing", FanWashingCategory::new).addTypedRecipes(AllRecipeTypes.SPLASHING) washing = register("fan_washing", FanWashingCategory::new).addTypedRecipes(AllRecipeTypes.SPLASHING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_washing")) .catalystStack(ProcessingViaFanCategory.getFan("fan_washing"))
.build(), .build(),
smoking = register("fan_smoking", FanSmokingCategory::new).addTypedRecipes(() -> RecipeType.SMOKING) smoking = register("fan_smoking", FanSmokingCategory::new).addTypedRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_smoking")) .catalystStack(ProcessingViaFanCategory.getFan("fan_smoking"))
.build(), .build(),
blasting = register("fan_blasting", FanBlastingCategory::new) blasting = register("fan_blasting", FanBlastingCategory::new)
.addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING) .addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING)
.addTypedRecipes(() -> RecipeType.BLASTING) .addTypedRecipes(() -> RecipeType.BLASTING)
.removeRecipes(() -> RecipeType.SMOKING) .removeRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting")) .catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(), .build(),
haunting = register("fan_haunting", FanHauntingCategory::new).addTypedRecipes(AllRecipeTypes.HAUNTING) haunting = register("fan_haunting", FanHauntingCategory::new).addTypedRecipes(AllRecipeTypes.HAUNTING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_haunting")).build(), .catalystStack(ProcessingViaFanCategory.getFan("fan_haunting"))
.build(),
mixing = register("mixing", MixingCategory::standard).addTypedRecipes(AllRecipeTypes.MIXING) mixing = register("mixing", MixingCategory::standard).addTypedRecipes(AllRecipeTypes.MIXING)
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.build(), .build(),
seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new) seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new)
.addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY) .addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY)
.build(), .build(),
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless) autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients() .addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
.size() > 1 && !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r), && r.getIngredients()
BasinRecipe::convertShapeless) .size() > 1
&& !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer) .enableWhen(c -> c.allowShapelessInMixer)
.build(), .build(),
brewing = register("automatic_brewing", MixingCategory::autoBrewing) brewing =
.addRecipes(() -> PotionMixingRecipes.ALL) register("automatic_brewing", MixingCategory::autoBrewing).addRecipes(() -> PotionMixingRecipes.ALL)
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.build(), .build(),
sawing = register("sawing", SawingCategory::new).addTypedRecipes(AllRecipeTypes.CUTTING) sawing = register("sawing", SawingCategory::new).addTypedRecipes(AllRecipeTypes.CUTTING)
.catalyst(AllBlocks.MECHANICAL_SAW::get) .catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(), .build(),
blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS)) blockCutting =
.addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding( register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
RecipeType.STONECUTTING, recipe -> AllRecipeTypes.isManualRecipe(recipe)))) .addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding(
.catalyst(AllBlocks.MECHANICAL_SAW::get) RecipeType.STONECUTTING, recipe -> AllRecipeTypes.shouldIgnoreInAutomation(recipe))))
.enableWhen(c -> c.allowStonecuttingOnSaw) .catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(), .enableWhen(c -> c.allowStonecuttingOnSaw)
.build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS)) woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe .addRecipes(() -> CondensedBlockCuttingRecipe
.condenseRecipes(getTypedRecipesExcluding(SawTileEntity.woodcuttingRecipeType.get(), .condenseRecipes(getTypedRecipesExcluding(SawTileEntity.woodcuttingRecipeType.get(),
recipe -> AllRecipeTypes.isManualRecipe(recipe)))) recipe -> AllRecipeTypes.shouldIgnoreInAutomation(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get) .catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get() .enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft")) .isLoaded("druidcraft"))
.build(), .build(),
packing = register("packing", PackingCategory::standard).addTypedRecipes(AllRecipeTypes.COMPACTING) packing = register("packing", PackingCategory::standard).addTypedRecipes(AllRecipeTypes.COMPACTING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.build(), .build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare) autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.addAllRecipesIf( .addAllRecipesIf(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe) r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r), && MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless) BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress) .enableWhen(c -> c.allowShapedSquareInPress)
.build(), .build(),
polishing = register("sandpaper_polishing", PolishingCategory::new).addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING) polishing = register("sandpaper_polishing", PolishingCategory::new)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING)
.catalyst(AllItems.SAND_PAPER::get) .catalyst(AllItems.SAND_PAPER::get)
.catalyst(AllItems.RED_SAND_PAPER::get) .catalyst(AllItems.RED_SAND_PAPER::get)
.build(), .build(),
deploying = register("deploying", DeployingCategory::new) deploying = register("deploying", DeployingCategory::new).addTypedRecipes(AllRecipeTypes.DEPLOYING)
.addTypedRecipes(AllRecipeTypes.DEPLOYING)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert) .addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert)
.catalyst(AllBlocks.DEPLOYER::get) .catalyst(AllBlocks.DEPLOYER::get)
.catalyst(AllBlocks.DEPOT::get) .catalyst(AllBlocks.DEPOT::get)
.catalyst(AllItems.BELT_CONNECTOR::get) .catalyst(AllItems.BELT_CONNECTOR::get)
.build(), .build(),
mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new) mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new)
.addRecipes(() -> MysteriousItemConversionCategory.RECIPES) .addRecipes(() -> MysteriousItemConversionCategory.RECIPES)
.build(), .build(),
spoutFilling = register("spout_filling", SpoutCategory::new).addTypedRecipes(AllRecipeTypes.FILLING) spoutFilling = register("spout_filling", SpoutCategory::new).addTypedRecipes(AllRecipeTypes.FILLING)
.addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager)) .addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager))
.catalyst(AllBlocks.SPOUT::get) .catalyst(AllBlocks.SPOUT::get)
.build(), .build(),
draining = register("draining", ItemDrainCategory::new) draining = register("draining", ItemDrainCategory::new)
.addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager)) .addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager))
.addTypedRecipes(AllRecipeTypes.EMPTYING) .addTypedRecipes(AllRecipeTypes.EMPTYING)
.catalyst(AllBlocks.ITEM_DRAIN::get) .catalyst(AllBlocks.ITEM_DRAIN::get)
.build(), .build(),
autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new) autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients() .addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
.size() == 1) && r.getIngredients()
.addTypedRecipesIf(() -> RecipeType.CRAFTING, recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.isManualRecipe(recipe)) .size() == 1
&& !AllRecipeTypes.shouldIgnoreInAutomation(r))
.addTypedRecipesIf(() -> RecipeType.CRAFTING,
recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.shouldIgnoreInAutomation(recipe))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter) .enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(), .build(),
mechanicalCrafting = register("mechanical_crafting", MechanicalCraftingCategory::new) mechanicalCrafting = register("mechanical_crafting", MechanicalCraftingCategory::new)
.addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING) .addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING)
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.build(); .build();
private <T extends Recipe<?>> CategoryBuilder<T> register(String name, }
Supplier<CreateRecipeCategory<T>> supplier) {
private <T extends Recipe<?>> CategoryBuilder<T> register(String name, Supplier<CreateRecipeCategory<T>> supplier) {
return new CategoryBuilder<T>(name, supplier); return new CategoryBuilder<T>(name, supplier);
} }
@ -236,6 +247,7 @@ public class CreateJEI implements IModPlugin {
@Override @Override
public void registerCategories(IRecipeCategoryRegistration registration) { public void registerCategories(IRecipeCategoryRegistration registration) {
loadCategories();
registration.addRecipeCategories(allCategories.toArray(IRecipeCategory[]::new)); registration.addRecipeCategories(allCategories.toArray(IRecipeCategory[]::new));
} }
@ -253,7 +265,7 @@ public class CreateJEI implements IModPlugin {
allCategories.forEach(c -> c.recipes.forEach(s -> registration.addRecipes(s.get(), c.getUid()))); allCategories.forEach(c -> c.recipes.forEach(s -> registration.addRecipes(s.get(), c.getUid())));
registration.addRecipes(ToolboxColoringRecipeMaker.createRecipes() registration.addRecipes(ToolboxColoringRecipeMaker.createRecipes()
.collect(Collectors.toList()), VanillaRecipeCategoryUid.CRAFTING); .collect(Collectors.toList()), VanillaRecipeCategoryUid.CRAFTING);
} }
@Override @Override
@ -261,7 +273,7 @@ public class CreateJEI implements IModPlugin {
allCategories.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getUid()))); allCategories.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getUid())));
} }
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
public void registerGuiHandlers(IGuiHandlerRegistration registration) { public void registerGuiHandlers(IGuiHandlerRegistration registration) {
registration.addGenericGuiContainerHandler(AbstractSimiContainerScreen.class, new SlotMover()); registration.addGenericGuiContainerHandler(AbstractSimiContainerScreen.class, new SlotMover());
@ -315,14 +327,15 @@ public class CreateJEI implements IModPlugin {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipes::add, recipeType.get())); return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipes::add, recipeType.get()));
} }
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType, Function<Recipe<?>, T> converter) { public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType,
Function<Recipe<?>, T> converter) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> { return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
recipes.add(converter.apply(recipe)); recipes.add(converter.apply(recipe));
}, recipeType.get())); }, recipeType.get()));
} }
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType, public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType,
Predicate<Recipe<?>> pred) { Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> { return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
if (pred.test(recipe)) { if (pred.test(recipe)) {
recipes.add(recipe); recipes.add(recipe);
@ -331,7 +344,7 @@ public class CreateJEI implements IModPlugin {
} }
public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType, public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType,
Supplier<RecipeType<? extends T>> excluded) { Supplier<RecipeType<? extends T>> excluded) {
return addRecipeListConsumer(recipes -> { return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get()); List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get());
consumeTypedRecipes(recipe -> { consumeTypedRecipes(recipe -> {
@ -361,7 +374,7 @@ public class CreateJEI implements IModPlugin {
public CategoryBuilder<T> catalyst(Supplier<ItemLike> supplier) { public CategoryBuilder<T> catalyst(Supplier<ItemLike> supplier) {
return catalystStack(() -> new ItemStack(supplier.get() return catalystStack(() -> new ItemStack(supplier.get()
.asItem())); .asItem()));
} }
public CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) { public CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) {
@ -371,7 +384,7 @@ public class CreateJEI implements IModPlugin {
public CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) { public CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) {
pred = c -> configValue.apply(c) pred = c -> configValue.apply(c)
.get(); .get();
return this; return this;
} }
@ -405,11 +418,10 @@ public class CreateJEI implements IModPlugin {
public static void consumeTypedRecipes(Consumer<Recipe<?>> consumer, RecipeType<?> type) { public static void consumeTypedRecipes(Consumer<Recipe<?>> consumer, RecipeType<?> type) {
Map<ResourceLocation, Recipe<?>> map = Minecraft.getInstance() Map<ResourceLocation, Recipe<?>> map = Minecraft.getInstance()
.getConnection() .getConnection()
.getRecipeManager() .getRecipeManager().recipes.get(type);
.recipes
.get(type);
if (map != null) { if (map != null) {
map.values().forEach(consumer); map.values()
.forEach(consumer);
} }
} }
@ -426,18 +438,21 @@ public class CreateJEI implements IModPlugin {
} }
public static boolean doInputsMatch(Recipe<?> recipe1, Recipe<?> recipe2) { public static boolean doInputsMatch(Recipe<?> recipe1, Recipe<?> recipe2) {
if (recipe1.getIngredients().isEmpty() || recipe2.getIngredients().isEmpty()) { if (recipe1.getIngredients()
.isEmpty()
|| recipe2.getIngredients()
.isEmpty()) {
return false; return false;
} }
ItemStack[] matchingStacks = recipe1.getIngredients() ItemStack[] matchingStacks = recipe1.getIngredients()
.get(0) .get(0)
.getItems(); .getItems();
if (matchingStacks.length == 0) { if (matchingStacks.length == 0) {
return false; return false;
} }
if (recipe2.getIngredients() if (recipe2.getIngredients()
.get(0) .get(0)
.test(matchingStacks[0])) .test(matchingStacks[0]))
return true; return true;
return false; return false;
} }

View file

@ -166,7 +166,7 @@ public class RecipeGridHandler {
if (numItems > 9) if (numItems > 9)
return false; return false;
} }
if (AllRecipeTypes.isManualRecipe(recipe)) if (AllRecipeTypes.shouldIgnoreInAutomation(recipe))
return false; return false;
return true; return true;
} }

View file

@ -87,8 +87,8 @@ public class CrushingWheelControllerBlock extends DirectionalBlock implements IT
return; return;
if (te.crushingspeed == 0) if (te.crushingspeed == 0)
return; return;
if (entityIn instanceof ItemEntity) // if (entityIn instanceof ItemEntity)
((ItemEntity) entityIn).setPickUpDelay(10); // ((ItemEntity) entityIn).setPickUpDelay(10);
CompoundTag data = entityIn.getPersistentData(); CompoundTag data = entityIn.getPersistentData();
if (data.contains("BypassCrushingWheel")) { if (data.contains("BypassCrushingWheel")) {
if (pos.equals(NbtUtils.readBlockPos(data.getCompound("BypassCrushingWheel")))) if (pos.equals(NbtUtils.readBlockPos(data.getCompound("BypassCrushingWheel"))))

View file

@ -81,7 +81,7 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity {
if (blockState == null) if (blockState == null)
return false; return false;
Direction direction = blockState.getValue(CrushingWheelControllerBlock.FACING); Direction direction = blockState.getValue(CrushingWheelControllerBlock.FACING);
return direction == Direction.DOWN || direction.getOpposite() == side; return direction == Direction.DOWN || direction == side;
} }
@Override @Override
@ -145,7 +145,7 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity {
// Output Items // Output Items
if (facing != Direction.UP) { if (facing != Direction.UP) {
Direction inputDir = facing.getOpposite(); Direction inputDir = facing;
BlockPos nextPos = worldPosition.offset(facing.getAxis() == Axis.X ? 1f * offset : 0f, (-1f), BlockPos nextPos = worldPosition.offset(facing.getAxis() == Axis.X ? 1f * offset : 0f, (-1f),
facing.getAxis() == Axis.Z ? 1f * offset : 0f); facing.getAxis() == Axis.Z ? 1f * offset : 0f);
DirectBeltInputBehaviour behaviour = DirectBeltInputBehaviour behaviour =

View file

@ -241,7 +241,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
return ((r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) return ((r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& AllConfigs.SERVER.recipes.allowShapelessInMixer.get() && r.getIngredients() && AllConfigs.SERVER.recipes.allowShapelessInMixer.get() && r.getIngredients()
.size() > 1 .size() > 1
&& !MechanicalPressTileEntity.canCompress(r)) && !AllRecipeTypes.isManualRecipe(r) && !MechanicalPressTileEntity.canCompress(r)) && !AllRecipeTypes.shouldIgnoreInAutomation(r)
|| r.getType() == AllRecipeTypes.MIXING.getType()); || r.getType() == AllRecipeTypes.MIXING.getType());
} }

View file

@ -3,9 +3,7 @@ package com.simibubi.create.content.contraptions.components.press;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
@ -32,7 +30,6 @@ import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -41,7 +38,6 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -345,17 +341,9 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
return AllRecipeTypes.PRESSING.find(pressingInv, level); return AllRecipeTypes.PRESSING.find(pressingInv, level);
} }
private static final Set<ResourceLocation> RECIPE_DENY_SET =
ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual"));
public static <C extends Container> boolean canCompress(Recipe<C> recipe) { public static <C extends Container> boolean canCompress(Recipe<C> recipe) {
if (!(recipe instanceof CraftingRecipe) || !AllConfigs.SERVER.recipes.allowShapedSquareInPress.get()) if (!(recipe instanceof CraftingRecipe) || !AllConfigs.SERVER.recipes.allowShapedSquareInPress.get())
return false; return false;
RecipeSerializer<?> serializer = recipe.getSerializer();
if (serializer != null && RECIPE_DENY_SET.contains(serializer.getRegistryName()))
return false;
NonNullList<Ingredient> ingredients = recipe.getIngredients(); NonNullList<Ingredient> ingredients = recipe.getIngredients();
return (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.matchAllIngredients(ingredients); return (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.matchAllIngredients(ingredients);
} }
@ -363,7 +351,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
@Override @Override
protected <C extends Container> boolean matchStaticFilters(Recipe<C> recipe) { protected <C extends Container> boolean matchStaticFilters(Recipe<C> recipe) {
return (recipe instanceof CraftingRecipe && !(recipe instanceof MechanicalCraftingRecipe) return (recipe instanceof CraftingRecipe && !(recipe instanceof MechanicalCraftingRecipe)
&& canCompress(recipe) && !AllRecipeTypes.isManualRecipe(recipe)) && canCompress(recipe) && !AllRecipeTypes.shouldIgnoreInAutomation(recipe))
|| recipe.getType() == AllRecipeTypes.COMPACTING.getType(); || recipe.getType() == AllRecipeTypes.COMPACTING.getType();
} }

View file

@ -365,7 +365,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return startedSearch.stream() return startedSearch.stream()
.filter(RecipeConditions.outputMatchesFilter(filtering)) .filter(RecipeConditions.outputMatchesFilter(filtering))
.filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0))) .filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0)))
.filter(r -> !AllRecipeTypes.isManualRecipe(r)) .filter(r -> !AllRecipeTypes.shouldIgnoreInAutomation(r))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }

View file

@ -64,7 +64,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
protected Contraption contraption; protected Contraption contraption;
protected boolean initialized; protected boolean initialized;
protected boolean prevPosInvalid; protected boolean prevPosInvalid;
private boolean ticking; private boolean skipActorStop;
public AbstractContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) { public AbstractContraptionEntity(EntityType<?> entityTypeIn, Level worldIn) {
super(entityTypeIn, worldIn); super(entityTypeIn, worldIn);
@ -222,7 +222,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return; return;
} }
collidingEntities.entrySet().removeIf(e -> e.getValue().incrementAndGet() > 3); collidingEntities.entrySet()
.removeIf(e -> e.getValue()
.incrementAndGet() > 3);
xo = getX(); xo = getX();
yo = getY(); yo = getY();
@ -248,7 +250,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
if (!level.isClientSide) if (!level.isClientSide)
contraption.stalled = false; contraption.stalled = false;
ticking = true; skipActorStop = true;
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) { for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = pair.right; MovementContext context = pair.right;
StructureBlockInfo blockInfo = pair.left; StructureBlockInfo blockInfo = pair.left;
@ -285,7 +287,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
contraption.stop(level); contraption.stop(level);
return; return;
} }
ticking = false; skipActorStop = false;
for (Entity entity : getPassengers()) { for (Entity entity : getPassengers()) {
if (!(entity instanceof OrientedContraptionEntity)) if (!(entity instanceof OrientedContraptionEntity))
@ -440,8 +442,10 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
return; return;
if (contraption == null) if (contraption == null)
return; return;
StructureTransform transform = makeStructureTransform(); StructureTransform transform = makeStructureTransform();
contraption.stop(level);
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
new ContraptionDisassemblyPacket(this.getId(), transform)); new ContraptionDisassemblyPacket(this.getId(), transform));
@ -460,8 +464,9 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
((AbstractContraptionEntity) entity).disassemble(); ((AbstractContraptionEntity) entity).disassemble();
} }
skipActorStop = true;
discard(); discard();
ejectPassengers(); ejectPassengers();
moveCollidedEntitiesOnDisassembly(transform); moveCollidedEntitiesOnDisassembly(transform);
AllSoundEvents.CONTRAPTION_DISASSEMBLE.playOnServer(level, blockPosition()); AllSoundEvents.CONTRAPTION_DISASSEMBLE.playOnServer(level, blockPosition());
@ -480,9 +485,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
@Override @Override
public void remove(RemovalReason p_146834_) { public void remove(RemovalReason p_146834_) {
if (!level.isClientSide && !isRemoved() && contraption != null) if (!level.isClientSide && !isRemoved() && contraption != null && !skipActorStop)
if (!ticking) contraption.stop(level);
contraption.stop(level);
if (contraption != null) if (contraption != null)
contraption.onEntityRemoved(this); contraption.onEntityRemoved(this);
super.remove(p_146834_); super.remove(p_146834_);

View file

@ -38,6 +38,7 @@ import net.minecraft.world.level.block.WeatheringCopperStairBlock;
import net.minecraft.world.level.block.state.BlockBehaviour.Properties; import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelProvider; import net.minecraftforge.client.model.generators.ModelProvider;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class CopperBlockSet { public class CopperBlockSet {
protected static final WeatherState[] WEATHER_STATES = WeatherState.values(); protected static final WeatherState[] WEATHER_STATES = WeatherState.values();
@ -325,7 +326,8 @@ public class CopperBlockSet {
new WeatheringCopperStairBlock(state, Blocks.AIR.defaultBlockState(), p); new WeatheringCopperStairBlock(state, Blocks.AIR.defaultBlockState(), p);
// WeatheringCopperStairBlock does not have a constructor that takes a Supplier, // WeatheringCopperStairBlock does not have a constructor that takes a Supplier,
// so setting the field directly is the easiest solution // so setting the field directly is the easiest solution
block.stateSupplier = defaultStateSupplier; ObfuscationReflectionHelper.setPrivateValue(StairBlock.class, block, defaultStateSupplier,
"stateSupplier");
return block; return block;
}; };
} }

View file

@ -26,7 +26,6 @@ public net.minecraft.world.item.crafting.RecipeManager f_44007_ # recipes
public net.minecraft.world.level.BaseSpawner f_45443_ # spawnPotentials public net.minecraft.world.level.BaseSpawner f_45443_ # spawnPotentials
public net.minecraft.world.level.BaseSpawner f_45444_ # nextSpawnData public net.minecraft.world.level.BaseSpawner f_45444_ # nextSpawnData
public net.minecraft.world.level.biome.BiomeManager f_47863_ # biomeZoomSeed public net.minecraft.world.level.biome.BiomeManager f_47863_ # biomeZoomSeed
public-f net.minecraft.world.level.block.StairBlock stateSupplier
public net.minecraft.world.level.block.entity.BeaconBlockEntity f_58648_ # beamSections public net.minecraft.world.level.block.entity.BeaconBlockEntity f_58648_ # beamSections
public net.minecraft.world.level.chunk.HashMapPalette f_62658_ # values public net.minecraft.world.level.chunk.HashMapPalette f_62658_ # values
public net.minecraft.world.level.chunk.PaletteResize public net.minecraft.world.level.chunk.PaletteResize

View file

@ -5,7 +5,7 @@ license="MIT"
[[mods]] [[mods]]
modId="create" modId="create"
version="0.4e" version="0.4f"
displayName="Create" displayName="Create"
#updateJSONURL="" #updateJSONURL=""
displayURL="https://www.curseforge.com/minecraft/mc-mods/create" displayURL="https://www.curseforge.com/minecraft/mc-mods/create"