Just enough brewing

- Optimize CreateJEI recipe list construction
- Optimize PotionMixingRecipes
- Add basic modded brewing recipe compatibility
- Fix dyed sails not being placed when printing schematics
- Fix sideways belts not being placed correctly when printing schematics
- Fix MechanicalCraftingCategory not applying the model matrix
- Add Upgrade Aquatic compatible fertilizer recipes; Resolve #658
- Replace almost all reflection with access transformers or accessor
mixins
- Remove duplicate sails tag
- Improve metal compatibility
- Switch to a linked set in StringSerializableTrigger to prevent
inconsistent generation of aesthetics.json
- Other minor changes
This commit is contained in:
PepperCode1 2022-03-12 00:04:05 -08:00
parent 9fe4aee271
commit 2211632f5c
54 changed files with 957 additions and 790 deletions

View file

@ -21,7 +21,7 @@ parchment_version = 2022.01.23
registrate_version = MC1.18-1.0.21
flywheel_version = 1.18-0.6.1.62
jei_minecraft_version = 1.18.1
jei_version = 9.3.2.92
jei_version = 9.4.1.112
# curseforge information
projectId = 328085

View file

@ -5186,7 +5186,6 @@ ac265a674626e0e832330086fd18fe0be37fc327 data/create/recipes/weathered_copper_ti
57b942386a15c874d1ca9cd6a8032c11a5599fc2 data/create/tags/blocks/fan_transparent.json
10781e8cfcbb3486327aace3aa00e437fb44b331 data/create/tags/blocks/ore_override_stone.json
557a29a61145b0f266760ef06256188a296739a7 data/create/tags/blocks/safe_nbt.json
c9ac7e3e5ec18554e7184168d65e9b8e44ef5610 data/create/tags/blocks/sails.json
6cdeeac1689f7b5bfd9bc40b462143d8eaf3ad0b data/create/tags/blocks/seats.json
d063e12c9ef75f39518c6d129ea35d833464d547 data/create/tags/blocks/toolboxes.json
50936b211d94167a35ec78c89954082a336b6269 data/create/tags/blocks/valve_handles.json

View file

@ -1,20 +0,0 @@
{
"replace": false,
"values": [
"create:orange_sail",
"create:magenta_sail",
"create:light_blue_sail",
"create:yellow_sail",
"create:lime_sail",
"create:pink_sail",
"create:gray_sail",
"create:light_gray_sail",
"create:cyan_sail",
"create:purple_sail",
"create:blue_sail",
"create:brown_sail",
"create:green_sail",
"create:red_sail",
"create:black_sail"
]
}

View file

@ -48,6 +48,7 @@ import com.simibubi.create.content.contraptions.components.motor.CreativeMotorGe
import com.simibubi.create.content.contraptions.components.press.MechanicalPressBlock;
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
import com.simibubi.create.content.contraptions.components.saw.SawGenerator;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BlankSailBlockItem;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock;
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.SailBlock;
@ -1125,7 +1126,8 @@ public class AllBlocks {
.transform(axeOnly())
.blockstate(BlockStateGen.directionalBlockProvider(false))
.tag(AllBlockTags.WINDMILL_SAILS.tag)
.simpleItem()
.item(BlankSailBlockItem::new)
.build()
.register();
public static final DyedBlockList<SailBlock> DYED_SAILS = new DyedBlockList<>(colour -> {
@ -1135,13 +1137,13 @@ public class AllBlocks {
String colourName = colour.getSerializedName();
return REGISTRATE.block(colourName + "_sail", p -> SailBlock.withCanvas(p, colour))
.initialProperties(SharedProperties::wooden)
.properties(BlockBehaviour.Properties::noOcclusion)
.properties(p -> p.sound(SoundType.SCAFFOLDING)
.noOcclusion())
.transform(axeOnly())
.blockstate((c, p) -> p.directionalBlock(c.get(), p.models()
.withExistingParent(colourName + "_sail", p.modLoc("block/white_sail"))
.texture("0", p.modLoc("block/sail/canvas_" + colourName))))
.tag(AllBlockTags.WINDMILL_SAILS.tag)
.tag(AllBlockTags.SAILS.tag)
.loot((p, b) -> p.dropOther(b, SAIL.get()))
.register();
});

View file

@ -9,6 +9,15 @@ import static com.simibubi.create.content.AllSections.KINETICS;
import static com.simibubi.create.content.AllSections.LOGISTICS;
import static com.simibubi.create.content.AllSections.MATERIALS;
import static com.simibubi.create.content.AllSections.SCHEMATICS;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.NICKEL;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.OSMIUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.PLATINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.QUICKSILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.SILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.TIN;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.URANIUM;
import com.simibubi.create.AllTags.AllItemTags;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem;
@ -45,6 +54,7 @@ import com.simibubi.create.content.schematics.item.SchematicAndQuillItem;
import com.simibubi.create.content.schematics.item.SchematicItem;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.data.recipe.CompatMetals;
import com.simibubi.create.foundation.item.HiddenIngredientItem;
import com.simibubi.create.foundation.item.TagDependentIngredientItem;
import com.simibubi.create.foundation.item.TooltipHelper;
@ -188,11 +198,11 @@ public class AllItems {
CRUSHED_COPPER = taggedIngredient("crushed_copper_ore", CRUSHED_ORES.tag),
CRUSHED_ZINC = taggedIngredient("crushed_zinc_ore", CRUSHED_ORES.tag);
public static final ItemEntry<TagDependentIngredientItem> CRUSHED_OSMIUM = compatCrushedOre("osmium"),
CRUSHED_PLATINUM = compatCrushedOre("platinum"), CRUSHED_SILVER = compatCrushedOre("silver"),
CRUSHED_TIN = compatCrushedOre("tin"), CRUSHED_LEAD = compatCrushedOre("lead"),
CRUSHED_QUICKSILVER = compatCrushedOre("quicksilver"), CRUSHED_BAUXITE = compatCrushedOre("aluminum"),
CRUSHED_URANIUM = compatCrushedOre("uranium"), CRUSHED_NICKEL = compatCrushedOre("nickel");
public static final ItemEntry<TagDependentIngredientItem> CRUSHED_OSMIUM = compatCrushedOre(OSMIUM),
CRUSHED_PLATINUM = compatCrushedOre(PLATINUM), CRUSHED_SILVER = compatCrushedOre(SILVER),
CRUSHED_TIN = compatCrushedOre(TIN), CRUSHED_LEAD = compatCrushedOre(LEAD),
CRUSHED_QUICKSILVER = compatCrushedOre(QUICKSILVER), CRUSHED_BAUXITE = compatCrushedOre(ALUMINUM),
CRUSHED_URANIUM = compatCrushedOre(URANIUM), CRUSHED_NICKEL = compatCrushedOre(NICKEL);
// Kinetics
@ -366,7 +376,8 @@ public class AllItems {
.register();
}
private static ItemEntry<TagDependentIngredientItem> compatCrushedOre(String metalName) {
private static ItemEntry<TagDependentIngredientItem> compatCrushedOre(CompatMetals metal) {
String metalName = metal.getName();
return REGISTRATE
.item("crushed_" + metalName + "_ore",
props -> new TagDependentIngredientItem(props, new ResourceLocation("forge", "ores/" + metalName)))

View file

@ -111,7 +111,6 @@ public class AllTags {
FAN_TRANSPARENT,
ORE_OVERRIDE_STONE,
SAFE_NBT,
SAILS,
SEATS,
TOOLBOXES,
VALVE_HANDLES,

View file

@ -1,7 +1,9 @@
package com.simibubi.create.compat.jei;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@ -42,7 +44,7 @@ import com.simibubi.create.content.contraptions.components.deployer.DeployerAppl
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid;
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipes;
import com.simibubi.create.content.contraptions.processing.BasinRecipe;
import com.simibubi.create.content.curiosities.tools.BlueprintScreen;
import com.simibubi.create.content.logistics.item.LinkedControllerScreen;
@ -56,6 +58,7 @@ import com.simibubi.create.foundation.utility.recipe.IRecipeTypeInfo;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IGuiHandlerRegistration;
import mezz.jei.api.registration.IRecipeCatalystRegistration;
import mezz.jei.api.registration.IRecipeCategoryRegistration;
@ -84,139 +87,136 @@ public class CreateJEI implements IModPlugin {
private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
private final CreateRecipeCategory<?>
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
milling = register("milling", MillingCategory::new).addTypedRecipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
crushing = register("crushing", CrushingCategory::new).recipes(AllRecipeTypes.CRUSHING)
.recipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
.catalyst(AllBlocks.CRUSHING_WHEEL::get)
.build(),
crushing = register("crushing", CrushingCategory::new).addTypedRecipes(AllRecipeTypes.CRUSHING)
.addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
.catalyst(AllBlocks.CRUSHING_WHEEL::get)
.build(),
pressing = register("pressing", PressingCategory::new).recipes(AllRecipeTypes.PRESSING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.build(),
pressing = register("pressing", PressingCategory::new).addTypedRecipes(AllRecipeTypes.PRESSING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.build(),
washing = register("fan_washing", FanWashingCategory::new).recipes(AllRecipeTypes.SPLASHING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_washing"))
.build(),
washing = register("fan_washing", FanWashingCategory::new).addTypedRecipes(AllRecipeTypes.SPLASHING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_washing"))
.build(),
smoking = register("fan_smoking", FanSmokingCategory::new).recipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_smoking"))
.build(),
smoking = register("fan_smoking", FanSmokingCategory::new).addTypedRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_smoking"))
.build(),
soul_smoking = register("fan_haunting", FanHauntingCategory::new).recipes(AllRecipeTypes.HAUNTING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_haunting")).build(),
blasting = register("fan_blasting", FanBlastingCategory::new)
.addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING)
.addTypedRecipes(() -> RecipeType.BLASTING)
.removeRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(),
blasting = register("fan_blasting", FanBlastingCategory::new)
.recipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING)
.recipes(() -> RecipeType.BLASTING)
.removeRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(),
haunting = register("fan_haunting", FanHauntingCategory::new).addTypedRecipes(AllRecipeTypes.HAUNTING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_haunting")).build(),
mixing = register("mixing", MixingCategory::standard).recipes(AllRecipeTypes.MIXING::getType)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
mixing = register("mixing", MixingCategory::standard).addTypedRecipes(AllRecipeTypes.MIXING)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new)
.recipes(AllRecipeTypes.SEQUENCED_ASSEMBLY::getType)
.build(),
seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new)
.addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY)
.build(),
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.recipes(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients()
.size() > 1 && !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer)
.build(),
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients()
.size() > 1 && !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer)
.build(),
brewing = register("automatic_brewing", MixingCategory::autoBrewing)
.recipeList(PotionMixingRecipeManager::getAllBrewingRecipes)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
brewing = register("automatic_brewing", MixingCategory::autoBrewing)
.addRecipes(() -> PotionMixingRecipes.ALL)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
sawing = register("sawing", SawingCategory::new).recipes(AllRecipeTypes.CUTTING)
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(),
sawing = register("sawing", SawingCategory::new).addTypedRecipes(AllRecipeTypes.CUTTING)
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(),
blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
.recipeList(() -> CondensedBlockCuttingRecipe.condenseRecipes(findRecipes(
recipe -> recipe.getType() == RecipeType.STONECUTTING && !AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhen(c -> c.allowStonecuttingOnSaw)
.build(),
blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding(
RecipeType.STONECUTTING, recipe -> AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhen(c -> c.allowStonecuttingOnSaw)
.build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.recipeList(() -> CondensedBlockCuttingRecipe
.condenseRecipes(findRecipes(recipe -> recipe.getType() == SawTileEntity.woodcuttingRecipeType.get()
&& !AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft"))
.build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe
.condenseRecipes(getTypedRecipesExcluding(SawTileEntity.woodcuttingRecipeType.get(),
recipe -> AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft"))
.build(),
packing = register("packing", PackingCategory::standard).recipes(AllRecipeTypes.COMPACTING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
packing = register("packing", PackingCategory::standard).addTypedRecipes(AllRecipeTypes.COMPACTING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.recipes(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress)
.build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.addAllRecipesIf(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress)
.build(),
polishing = register("sandpaper_polishing", PolishingCategory::new).recipes(AllRecipeTypes.SANDPAPER_POLISHING)
.catalyst(AllItems.SAND_PAPER::get)
.catalyst(AllItems.RED_SAND_PAPER::get)
.build(),
polishing = register("sandpaper_polishing", PolishingCategory::new).addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING)
.catalyst(AllItems.SAND_PAPER::get)
.catalyst(AllItems.RED_SAND_PAPER::get)
.build(),
deploying = register("deploying", DeployingCategory::new)
.recipeList(() -> DeployerApplicationRecipe
.convert(findRecipesByType(AllRecipeTypes.SANDPAPER_POLISHING.getType())))
.recipes(AllRecipeTypes.DEPLOYING)
.catalyst(AllBlocks.DEPLOYER::get)
.catalyst(AllBlocks.DEPOT::get)
.catalyst(AllItems.BELT_CONNECTOR::get)
.build(),
deploying = register("deploying", DeployingCategory::new)
.addTypedRecipes(AllRecipeTypes.DEPLOYING)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert)
.catalyst(AllBlocks.DEPLOYER::get)
.catalyst(AllBlocks.DEPOT::get)
.catalyst(AllItems.BELT_CONNECTOR::get)
.build(),
mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new)
.recipeList(MysteriousItemConversionCategory::getRecipes)
.build(),
mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new)
.addRecipes(() -> MysteriousItemConversionCategory.RECIPES)
.build(),
spoutFilling = register("spout_filling", SpoutCategory::new).recipes(AllRecipeTypes.FILLING)
.recipeList(() -> SpoutCategory.getRecipes(ingredientManager))
.catalyst(AllBlocks.SPOUT::get)
.build(),
spoutFilling = register("spout_filling", SpoutCategory::new).addTypedRecipes(AllRecipeTypes.FILLING)
.addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager))
.catalyst(AllBlocks.SPOUT::get)
.build(),
draining = register("draining", ItemDrainCategory::new)
.recipeList(() -> ItemDrainCategory.getRecipes(ingredientManager))
.recipes(AllRecipeTypes.EMPTYING)
.catalyst(AllBlocks.ITEM_DRAIN::get)
.build(),
draining = register("draining", ItemDrainCategory::new)
.addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager))
.addTypedRecipes(AllRecipeTypes.EMPTYING)
.catalyst(AllBlocks.ITEM_DRAIN::get)
.build(),
autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new)
.recipes(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients()
.size() == 1)
.recipes(r -> (r.getType() == RecipeType.CRAFTING
&& r.getType() != AllRecipeTypes.MECHANICAL_CRAFTING.getType()) && (r instanceof IShapedRecipe<?>)
&& !AllRecipeTypes.isManualRecipe(r))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(),
autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>) && r.getIngredients()
.size() == 1)
.addTypedRecipesIf(() -> RecipeType.CRAFTING, recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.isManualRecipe(recipe))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(),
mechanicalCrafting =
register("mechanical_crafting", MechanicalCraftingCategory::new).recipes(AllRecipeTypes.MECHANICAL_CRAFTING)
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.build();
mechanicalCrafting = register("mechanical_crafting", MechanicalCraftingCategory::new)
.addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING)
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.build();
private <T extends Recipe<?>> CategoryBuilder<T> register(String name,
Supplier<CreateRecipeCategory<T>> supplier) {
@ -236,7 +236,7 @@ public class CreateJEI implements IModPlugin {
@Override
public void registerCategories(IRecipeCategoryRegistration registration) {
allCategories.forEach(registration::addRecipeCategories);
registration.addRecipeCategories(allCategories.toArray(IRecipeCategory[]::new));
}
@Override
@ -282,58 +282,81 @@ public class CreateJEI implements IModPlugin {
pred = Predicates.alwaysTrue();
}
public CategoryBuilder<T> recipes(IRecipeTypeInfo recipeTypeEntry) {
return recipes(recipeTypeEntry::getType);
}
public CategoryBuilder<T> recipes(Supplier<RecipeType<? extends T>> recipeType) {
return recipes(r -> r.getType() == recipeType.get());
}
public CategoryBuilder<T> recipes(ResourceLocation serializer) {
return recipes(r -> r.getSerializer()
.getRegistryName()
.equals(serializer));
}
public CategoryBuilder<T> recipes(Predicate<Recipe<?>> pred) {
return recipeList(() -> findRecipes(pred));
}
public CategoryBuilder<T> recipes(Predicate<Recipe<?>> pred, Function<Recipe<?>, T> converter) {
return recipeList(() -> findRecipes(pred), converter);
}
public CategoryBuilder<T> recipeList(Supplier<List<? extends Recipe<?>>> list) {
return recipeList(list, null);
}
public CategoryBuilder<T> recipeList(Supplier<List<? extends Recipe<?>>> list,
Function<Recipe<?>, T> converter) {
recipeListConsumers.add(recipes -> {
List<? extends Recipe<?>> toAdd = list.get();
if (converter != null)
toAdd = toAdd.stream()
.map(converter)
.collect(Collectors.toList());
recipes.addAll(toAdd);
});
public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<Recipe<?>>> consumer) {
recipeListConsumers.add(consumer);
return this;
}
public CategoryBuilder<T> recipesExcluding(Supplier<RecipeType<? extends T>> recipeType,
Supplier<RecipeType<? extends T>> excluded) {
recipeListConsumers.add(recipes -> {
recipes.addAll(findRecipesByTypeExcluding(recipeType.get(), excluded.get()));
public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends Recipe<?>>> collection) {
return addRecipeListConsumer(recipes -> recipes.addAll(collection.get()));
}
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
if (pred.test(recipe)) {
recipes.add(recipe);
}
}));
}
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred, Function<Recipe<?>, T> converter) {
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
if (pred.test(recipe)) {
recipes.add(converter.apply(recipe));
}
}));
}
public CategoryBuilder<T> addTypedRecipes(IRecipeTypeInfo recipeTypeEntry) {
return addTypedRecipes(recipeTypeEntry::getType);
}
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipes::add, recipeType.get()));
}
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType, Function<Recipe<?>, T> converter) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
recipes.add(converter.apply(recipe));
}, recipeType.get()));
}
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType,
Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
if (pred.test(recipe)) {
recipes.add(recipe);
}
}, recipeType.get()));
}
public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType,
Supplier<RecipeType<? extends T>> excluded) {
return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get());
consumeTypedRecipes(recipe -> {
for (Recipe<?> excludedRecipe : excludedRecipes) {
if (doInputsMatch(recipe, excludedRecipe)) {
return;
}
}
recipes.add(recipe);
}, recipeType.get());
});
return this;
}
public CategoryBuilder<T> removeRecipes(Supplier<RecipeType<? extends T>> recipeType) {
recipeListConsumers.add(recipes -> {
removeRecipesByType(recipes, recipeType.get());
return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(recipeType.get());
recipes.removeIf(recipe -> {
for (Recipe<?> excludedRecipe : excludedRecipes) {
if (doInputsMatch(recipe, excludedRecipe)) {
return true;
}
}
return false;
});
});
return this;
}
public CategoryBuilder<T> catalyst(Supplier<ItemLike> supplier) {
@ -371,49 +394,47 @@ public class CreateJEI implements IModPlugin {
}
public static List<Recipe<?>> findRecipes(Predicate<Recipe<?>> predicate) {
return Minecraft.getInstance()
public static void consumeAllRecipes(Consumer<Recipe<?>> consumer) {
Minecraft.getInstance()
.getConnection()
.getRecipeManager()
.getRecipes()
.stream()
.filter(predicate)
.collect(Collectors.toList());
.forEach(consumer);
}
public static List<Recipe<?>> findRecipesByType(RecipeType<?> type) {
return findRecipes(recipe -> recipe.getType() == type);
public static void consumeTypedRecipes(Consumer<Recipe<?>> consumer, RecipeType<?> type) {
Map<ResourceLocation, Recipe<?>> map = Minecraft.getInstance()
.getConnection()
.getRecipeManager()
.recipes
.get(type);
if (map != null) {
map.values().forEach(consumer);
}
}
public static List<Recipe<?>> findRecipesByTypeExcluding(RecipeType<?> type, RecipeType<?> excludingType) {
List<Recipe<?>> byType = findRecipesByType(type);
removeRecipesByType(byType, excludingType);
return byType;
public static List<Recipe<?>> getTypedRecipes(RecipeType<?> type) {
List<Recipe<?>> recipes = new ArrayList<>();
consumeTypedRecipes(recipes::add, type);
return recipes;
}
public static List<Recipe<?>> findRecipesByTypeExcluding(RecipeType<?> type, RecipeType<?>... excludingTypes) {
List<Recipe<?>> byType = findRecipesByType(type);
for (RecipeType<?> excludingType : excludingTypes)
removeRecipesByType(byType, excludingType);
return byType;
}
public static void removeRecipesByType(List<Recipe<?>> recipes, RecipeType<?> type) {
List<Recipe<?>> byType = findRecipesByType(type);
recipes.removeIf(recipe -> {
for (Recipe<?> r : byType)
if (doInputsMatch(recipe, r))
return true;
return false;
});
public static List<Recipe<?>> getTypedRecipesExcluding(RecipeType<?> type, Predicate<Recipe<?>> exclusionPred) {
List<Recipe<?>> recipes = getTypedRecipes(type);
recipes.removeIf(exclusionPred);
return recipes;
}
public static boolean doInputsMatch(Recipe<?> recipe1, Recipe<?> recipe2) {
if (recipe1.getIngredients().isEmpty() || recipe2.getIngredients().isEmpty()) {
return false;
}
ItemStack[] matchingStacks = recipe1.getIngredients()
.get(0)
.getItems();
if (matchingStacks.length == 0)
return true;
if (matchingStacks.length == 0) {
return false;
}
if (recipe2.getIngredients()
.get(0)
.test(matchingStacks[0]))

View file

@ -86,7 +86,7 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
public List<ItemStack> getOutputs() {
return outputs;
}
public List<List<ItemStack>> getCondensedOutputs() {
List<List<ItemStack>> result = new ArrayList<>();
int index = 0;
@ -104,6 +104,11 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
return result;
}
@Override
public boolean isSpecial() {
return true;
}
public static List<CondensedBlockCuttingRecipe> condenseRecipes(List<Recipe<?>> stoneCuttingRecipes) {
List<CondensedBlockCuttingRecipe> condensed = new ArrayList<>();
Recipes: for (Recipe<?> recipe : stoneCuttingRecipes) {
@ -120,11 +125,6 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
}
return condensed;
}
@Override
public boolean isSpecial() {
return true;
}
}

View file

@ -1,9 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.vertex.PoseStack;
@ -41,53 +41,47 @@ public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
drain = new AnimatedItemDrain();
}
public static List<EmptyingRecipe> getRecipes(IIngredientManager ingredientManager) {
List<EmptyingRecipe> recipes = new ArrayList<>();
public static void consumeRecipes(Consumer<EmptyingRecipe> consumer, IIngredientManager ingredientManager) {
for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM)) {
if (stack.getItem() instanceof PotionItem) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient potion = Ingredient.of(stack);
consumer.accept(new ProcessingRecipeBuilder<>(EmptyingRecipe::new, Create.asResource("potions"))
.withItemIngredients(potion)
.withFluidOutputs(fluidFromPotionItem)
.withSingleItemOutput(new ItemStack(Items.GLASS_BOTTLE))
.build());
return;
}
ingredientManager.getAllIngredients(VanillaTypes.ITEM)
.stream()
.forEach(stack -> {
if (stack.getItem() instanceof PotionItem) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient potion = Ingredient.of(stack);
recipes.add(new ProcessingRecipeBuilder<>(EmptyingRecipe::new, Create.asResource("potions"))
.withItemIngredients(potion)
.withFluidOutputs(fluidFromPotionItem)
.withSingleItemOutput(new ItemStack(Items.GLASS_BOTTLE))
LazyOptional<IFluidHandlerItem> capability =
stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
if (!capability.isPresent())
return;
ItemStack copy = stack.copy();
capability = copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
IFluidHandlerItem handler = capability.orElse(null);
FluidStack extracted = handler.drain(1000, FluidAction.EXECUTE);
ItemStack result = handler.getContainer();
if (extracted.isEmpty())
return;
if (result.isEmpty())
return;
Ingredient ingredient = Ingredient.of(stack);
ResourceLocation itemName = stack.getItem()
.getRegistryName();
ResourceLocation fluidName = extracted.getFluid()
.getRegistryName();
consumer.accept(new ProcessingRecipeBuilder<>(EmptyingRecipe::new,
Create.asResource("empty_" + itemName.getNamespace() + "_" + itemName.getPath() + "_of_"
+ fluidName.getNamespace() + "_" + fluidName.getPath())).withItemIngredients(ingredient)
.withFluidOutputs(extracted)
.withSingleItemOutput(result)
.build());
return;
}
LazyOptional<IFluidHandlerItem> capability =
stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
if (!capability.isPresent())
return;
ItemStack copy = stack.copy();
capability = copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
IFluidHandlerItem handler = capability.orElse(null);
FluidStack extracted = handler.drain(1000, FluidAction.EXECUTE);
ItemStack result = handler.getContainer();
if (extracted.isEmpty())
return;
if (result.isEmpty())
return;
Ingredient ingredient = Ingredient.of(stack);
ResourceLocation itemName = stack.getItem()
.getRegistryName();
ResourceLocation fluidName = extracted.getFluid()
.getRegistryName();
recipes.add(new ProcessingRecipeBuilder<>(EmptyingRecipe::new,
Create.asResource("empty_" + itemName.getNamespace() + "_" + itemName.getPath() + "_of_"
+ fluidName.getNamespace() + "_" + fluidName.getPath())).withItemIngredients(ingredient)
.withFluidOutputs(extracted)
.withSingleItemOutput(result)
.build());
});
return recipes;
}
}
@Override

View file

@ -155,6 +155,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
modelViewStack.pushPose();
modelViewStack.mulPoseMatrix(matrixStack.last()
.pose());
RenderSystem.applyModelViewMatrix();
RenderSystem.enableDepthTest();
Minecraft minecraft = Minecraft.getInstance();
Font font = getFontRenderer(minecraft, ingredient);
@ -163,6 +164,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
itemRenderer.renderGuiItemDecorations(font, ingredient, xPosition, yPosition, null);
RenderSystem.disableBlend();
modelViewStack.popPose();
RenderSystem.applyModelViewMatrix();
}
matrixStack.popPose();

View file

@ -18,13 +18,13 @@ import mezz.jei.api.ingredients.IIngredients;
public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> {
public static List<ConversionRecipe> getRecipes() {
List<ConversionRecipe> recipes = new ArrayList<>();
recipes.add(ConversionRecipe.create(AllItems.EMPTY_BLAZE_BURNER.asStack(), AllBlocks.BLAZE_BURNER.asStack()));
recipes.add(ConversionRecipe.create(AllItems.CHROMATIC_COMPOUND.asStack(), AllItems.SHADOW_STEEL.asStack()));
recipes.add(ConversionRecipe.create(AllItems.CHROMATIC_COMPOUND.asStack(), AllItems.REFINED_RADIANCE.asStack()));
recipes.add(ConversionRecipe.create(AllBlocks.PECULIAR_BELL.asStack(), AllBlocks.HAUNTED_BELL.asStack()));
return recipes;
public static final List<ConversionRecipe> RECIPES = new ArrayList<>();
static {
RECIPES.add(ConversionRecipe.create(AllItems.EMPTY_BLAZE_BURNER.asStack(), AllBlocks.BLAZE_BURNER.asStack()));
RECIPES.add(ConversionRecipe.create(AllBlocks.PECULIAR_BELL.asStack(), AllBlocks.HAUNTED_BELL.asStack()));
RECIPES.add(ConversionRecipe.create(AllItems.CHROMATIC_COMPOUND.asStack(), AllItems.SHADOW_STEEL.asStack()));
RECIPES.add(ConversionRecipe.create(AllItems.CHROMATIC_COMPOUND.asStack(), AllItems.REFINED_RADIANCE.asStack()));
}
public MysteriousItemConversionCategory() {

View file

@ -1,9 +1,10 @@
package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
@ -44,62 +45,55 @@ public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
spout = new AnimatedSpout();
}
public static List<FillingRecipe> getRecipes(IIngredientManager ingredientManager) {
List<FillingRecipe> recipes = new ArrayList<>();
public static void consumeRecipes(Consumer<FillingRecipe> consumer, IIngredientManager ingredientManager) {
Collection<FluidStack> fluidStacks = ingredientManager.getAllIngredients(VanillaTypes.FLUID);
for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM)) {
if (stack.getItem() instanceof PotionItem) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient bottle = Ingredient.of(Items.GLASS_BOTTLE);
consumer.accept(new ProcessingRecipeBuilder<>(FillingRecipe::new, Create.asResource("potions"))
.withItemIngredients(bottle)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidFromPotionItem))
.withSingleItemOutput(stack)
.build());
return;
}
ingredientManager.getAllIngredients(VanillaTypes.ITEM)
.stream()
.forEach(stack -> {
if (stack.getItem() instanceof PotionItem) {
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack);
Ingredient bottle = Ingredient.of(Items.GLASS_BOTTLE);
recipes.add(new ProcessingRecipeBuilder<>(FillingRecipe::new, Create.asResource("potions"))
.withItemIngredients(bottle)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidFromPotionItem))
.withSingleItemOutput(stack)
.build());
return;
}
LazyOptional<IFluidHandlerItem> capability =
stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
if (!capability.isPresent())
return;
LazyOptional<IFluidHandlerItem> capability =
stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
if (!capability.isPresent())
return;
for (FluidStack fluidStack : fluidStacks) {
ItemStack copy = stack.copy();
copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)
.ifPresent(fhi -> {
if (!GenericItemFilling.isFluidHandlerValid(copy, fhi))
return;
FluidStack fluidCopy = fluidStack.copy();
fluidCopy.setAmount(1000);
fhi.fill(fluidCopy, FluidAction.EXECUTE);
ItemStack container = fhi.getContainer();
if (container.sameItem(copy))
return;
if (container.isEmpty())
return;
ingredientManager.getAllIngredients(VanillaTypes.FLUID)
.stream()
.forEach(fluidStack -> {
ItemStack copy = stack.copy();
copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY)
.ifPresent(fhi -> {
if (!GenericItemFilling.isFluidHandlerValid(copy, fhi))
return;
FluidStack fluidCopy = fluidStack.copy();
fluidCopy.setAmount(1000);
fhi.fill(fluidCopy, FluidAction.EXECUTE);
ItemStack container = fhi.getContainer();
if (container.sameItem(copy))
return;
if (container.isEmpty())
return;
Ingredient bucket = Ingredient.of(stack);
ResourceLocation itemName = stack.getItem()
.getRegistryName();
ResourceLocation fluidName = fluidCopy.getFluid()
.getRegistryName();
recipes.add(new ProcessingRecipeBuilder<>(FillingRecipe::new,
Create.asResource("fill_" + itemName.getNamespace() + "_" + itemName.getPath()
+ "_with_" + fluidName.getNamespace() + "_" + fluidName.getPath()))
.withItemIngredients(bucket)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidCopy))
.withSingleItemOutput(container)
.build());
});
Ingredient bucket = Ingredient.of(stack);
ResourceLocation itemName = stack.getItem()
.getRegistryName();
ResourceLocation fluidName = fluidCopy.getFluid()
.getRegistryName();
consumer.accept(new ProcessingRecipeBuilder<>(FillingRecipe::new,
Create.asResource("fill_" + itemName.getNamespace() + "_" + itemName.getPath()
+ "_with_" + fluidName.getNamespace() + "_" + fluidName.getPath()))
.withItemIngredients(bucket)
.withFluidIngredients(FluidIngredient.fromFluidStack(fluidCopy))
.withSingleItemOutput(container)
.build());
});
});
return recipes;
}
}
}
@Override

View file

@ -1,20 +1,17 @@
package com.simibubi.create.content.contraptions.components.actors.dispenser;
import java.lang.reflect.Method;
import javax.annotation.Nullable;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.mixin.accessor.AbstractProjectileDispenseBehaviorAccessor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Position;
import net.minecraft.core.dispenser.AbstractProjectileDispenseBehavior;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public abstract class MovedProjectileDispenserBehaviour extends MovedDefaultDispenseItemBehaviour {
@ -50,51 +47,22 @@ public abstract class MovedProjectileDispenserBehaviour extends MovedDefaultDisp
}
public static MovedProjectileDispenserBehaviour of(AbstractProjectileDispenseBehavior vanillaBehaviour) {
AbstractProjectileDispenseBehaviorAccessor accessor = (AbstractProjectileDispenseBehaviorAccessor) vanillaBehaviour;
return new MovedProjectileDispenserBehaviour() {
@Override
protected Projectile getProjectileEntity(Level world, double x, double y, double z, ItemStack itemStack) {
try {
return (Projectile) MovedProjectileDispenserBehaviour.getProjectileEntityLookup().invoke(vanillaBehaviour, world, new SimplePos(x, y, z) , itemStack);
} catch (Throwable ignored) {
}
return null;
return accessor.create$callGetProjectile(world, new SimplePos(x, y, z), itemStack);
}
@Override
protected float getProjectileInaccuracy() {
try {
return (float) MovedProjectileDispenserBehaviour.getProjectileInaccuracyLookup().invoke(vanillaBehaviour);
} catch (Throwable ignored) {
}
return super.getProjectileInaccuracy();
return accessor.create$callGetUncertainty();
}
@Override
protected float getProjectileVelocity() {
try {
return (float) MovedProjectileDispenserBehaviour.getProjectileVelocityLookup().invoke(vanillaBehaviour);
} catch (Throwable ignored) {
}
return super.getProjectileVelocity();
return accessor.create$callGetPower();
}
};
}
private static Method getProjectileEntityLookup() {
Method getProjectileEntity = ObfuscationReflectionHelper.findMethod(AbstractProjectileDispenseBehavior.class, "m_6895_", Level.class, Position.class, ItemStack.class); // getProjectile
getProjectileEntity.setAccessible(true);
return getProjectileEntity;
}
private static Method getProjectileInaccuracyLookup() {
Method getProjectileInaccuracy = ObfuscationReflectionHelper.findMethod(AbstractProjectileDispenseBehavior.class, "m_7101_"); // getUncertainty
getProjectileInaccuracy.setAccessible(true);
return getProjectileInaccuracy;
}
private static Method getProjectileVelocityLookup() {
Method getProjectileVelocity = ObfuscationReflectionHelper.findMethod(AbstractProjectileDispenseBehavior.class, "m_7104_"); // getPower
getProjectileVelocity.setAccessible(true);
return getProjectileVelocity;
}
}

View file

@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.deployer;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import com.google.gson.JsonObject;
import com.simibubi.create.AllBlocks;
@ -74,17 +73,15 @@ public class DeployerApplicationRecipe extends ProcessingRecipe<RecipeWrapper> i
return ingredients.get(0);
}
public static List<DeployerApplicationRecipe> convert(List<Recipe<?>> sandpaperRecipes) {
return sandpaperRecipes.stream()
.map(r -> new ProcessingRecipeBuilder<>(DeployerApplicationRecipe::new, new ResourceLocation(r.getId()
.getNamespace(),
r.getId()
.getPath() + "_using_deployer")).require(r.getIngredients()
public static DeployerApplicationRecipe convert(Recipe<?> sandpaperRecipe) {
return new ProcessingRecipeBuilder<>(DeployerApplicationRecipe::new,
new ResourceLocation(sandpaperRecipe.getId().getNamespace(),
sandpaperRecipe.getId().getPath() + "_using_deployer"))
.require(sandpaperRecipe.getIngredients()
.get(0))
.require(AllItemTags.SANDPAPER.tag)
.output(r.getResultItem())
.build())
.collect(Collectors.toList());
.require(AllItemTags.SANDPAPER.tag)
.output(sandpaperRecipe.getResultItem())
.build();
}
@Override

View file

@ -7,7 +7,7 @@ import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
import com.simibubi.create.content.contraptions.fluids.FluidFX;
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipes;
import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity;
import com.simibubi.create.content.contraptions.processing.BasinTileEntity;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
@ -225,7 +225,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
if (stack.isEmpty())
continue;
List<MixingRecipe> list = PotionMixingRecipeManager.ALL.get(stack.getItem());
List<MixingRecipe> list = PotionMixingRecipes.BY_ITEM.get(stack.getItem());
if (list == null)
continue;
for (MixingRecipe mixingRecipe : list)

View file

@ -51,7 +51,6 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.entity.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
@ -551,8 +550,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
for (Entity entity : passengers) {
// setPos has world accessing side-effects when removed == null
String srg = "f_146795_"; // removalReason
ObfuscationReflectionHelper.setPrivateValue(Entity.class, entity, RemovalReason.UNLOADED_TO_CHUNK, srg);
entity.removalReason = RemovalReason.UNLOADED_TO_CHUNK;
// Gather passengers into same chunk when saving
Vec3 prevVec = entity.position();
@ -560,7 +558,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
// Super requires all passengers to not be removed in order to write them to the
// tag
ObfuscationReflectionHelper.setPrivateValue(Entity.class, entity, null, srg);
entity.removalReason = null;
}
CompoundTag tag = super.saveWithoutId(nbt);

View file

@ -0,0 +1,32 @@
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
import java.util.Map;
import com.simibubi.create.AllBlocks;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
public class BlankSailBlockItem extends BlockItem {
public BlankSailBlockItem(Block block, Properties properties) {
super(block, properties);
}
@Override
public void registerBlocks(Map<Block, Item> blockToItemMap, Item item) {
super.registerBlocks(blockToItemMap, item);
for (BlockEntry<SailBlock> entry : AllBlocks.DYED_SAILS) {
blockToItemMap.put(entry.get(), item);
}
}
@Override
public void removeFromBlockToItemMap(Map<Block, Item> blockToItemMap, Item item) {
super.removeFromBlockToItemMap(blockToItemMap, item);
for (BlockEntry<SailBlock> entry : AllBlocks.DYED_SAILS) {
blockToItemMap.remove(entry.get());
}
}
}

View file

@ -20,12 +20,14 @@ import com.simibubi.create.foundation.utility.placement.PlacementOffset;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.NonNullList;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShearsItem;
@ -62,6 +64,13 @@ public class SailBlock extends WrenchableDirectionalBlock {
this.color = color;
}
@Override
public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> items) {
if (frame || color == DyeColor.WHITE) {
super.fillItemCategory(tab, items);
}
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockState state = super.getStateForPlacement(context);

View file

@ -24,22 +24,49 @@ import net.minecraftforge.registries.ForgeRegistries;
public class PotionFluid extends VirtualFluid {
public enum BottleType {
REGULAR, SPLASH, LINGERING;
}
public PotionFluid(Properties properties) {
super(properties);
}
public static FluidStack withEffects(int amount, Potion potion, List<MobEffectInstance> customEffects) {
public static FluidStack of(int amount, Potion potion) {
FluidStack fluidStack = new FluidStack(AllFluids.POTION.get()
.getSource(), amount);
addPotionToFluidStack(fluidStack, potion);
return fluidStack;
}
public static FluidStack withEffects(int amount, Potion potion, List<MobEffectInstance> customEffects) {
FluidStack fluidStack = of(amount, potion);
appendEffects(fluidStack, customEffects);
return fluidStack;
}
public static FluidStack addPotionToFluidStack(FluidStack fs, Potion potion) {
ResourceLocation resourcelocation = ForgeRegistries.POTIONS.getKey(potion);
if (potion == Potions.EMPTY) {
fs.removeChildTag("Potion");
return fs;
}
fs.getOrCreateTag()
.putString("Potion", resourcelocation.toString());
return fs;
}
public static FluidStack appendEffects(FluidStack fs, Collection<MobEffectInstance> customEffects) {
if (customEffects.isEmpty())
return fs;
CompoundTag compoundnbt = fs.getOrCreateTag();
ListTag listnbt = compoundnbt.getList("CustomPotionEffects", 9);
for (MobEffectInstance effectinstance : customEffects)
listnbt.add(effectinstance.save(new CompoundTag()));
compoundnbt.put("CustomPotionEffects", listnbt);
return fs;
}
public enum BottleType {
REGULAR, SPLASH, LINGERING;
}
public static class PotionFluidAttributes extends FluidAttributes {
public PotionFluidAttributes(Builder builder, Fluid fluid) {
@ -70,26 +97,4 @@ public class PotionFluid extends VirtualFluid {
}
public static FluidStack addPotionToFluidStack(FluidStack fs, Potion potion) {
ResourceLocation resourcelocation = ForgeRegistries.POTIONS.getKey(potion);
if (potion == Potions.EMPTY) {
fs.removeChildTag("Potion");
return fs;
}
fs.getOrCreateTag()
.putString("Potion", resourcelocation.toString());
return fs;
}
public static FluidStack appendEffects(FluidStack fs, Collection<MobEffectInstance> customEffects) {
if (customEffects.isEmpty())
return fs;
CompoundTag compoundnbt = fs.getOrCreateTag();
ListTag listnbt = compoundnbt.getList("CustomPotionEffects", 9);
for (MobEffectInstance effectinstance : customEffects)
listnbt.add(effectinstance.save(new CompoundTag()));
compoundnbt.put("CustomPotionEffects", listnbt);
return fs;
}
}

View file

@ -51,16 +51,23 @@ public class PotionFluidHandler {
public static FluidStack getFluidFromPotionItem(ItemStack stack) {
Potion potion = PotionUtils.getPotion(stack);
List<MobEffectInstance> list = PotionUtils.getCustomEffects(stack);
FluidStack fluid = PotionFluid.withEffects(250, potion, list);
BottleType bottleTypeFromItem = bottleTypeFromItem(stack);
BottleType bottleTypeFromItem = bottleTypeFromItem(stack.getItem());
if (potion == Potions.WATER && list.isEmpty() && bottleTypeFromItem == BottleType.REGULAR)
return new FluidStack(Fluids.WATER, fluid.getAmount());
return new FluidStack(Fluids.WATER, 250);
FluidStack fluid = PotionFluid.withEffects(250, potion, list);
NBTHelper.writeEnum(fluid.getOrCreateTag(), "Bottle", bottleTypeFromItem);
return fluid;
}
public static BottleType bottleTypeFromItem(ItemStack stack) {
Item item = stack.getItem();
public static FluidStack getFluidFromPotion(Potion potion, BottleType bottleType, int amount) {
if (potion == Potions.WATER && bottleType == BottleType.REGULAR)
return new FluidStack(Fluids.WATER, amount);
FluidStack fluid = PotionFluid.of(amount, potion);
NBTHelper.writeEnum(fluid.getOrCreateTag(), "Bottle", bottleType);
return fluid;
}
public static BottleType bottleTypeFromItem(Item item) {
if (item == Items.LINGERING_POTION)
return BottleType.LINGERING;
if (item == Items.SPLASH_POTION)

View file

@ -1,20 +0,0 @@
package com.simibubi.create.content.contraptions.fluids.recipe;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
public class FluidTransferRecipes {
public static List<ItemStack> POTION_ITEMS = new ArrayList<>();
public static List<Item> FILLED_BUCKETS = new ArrayList<>();
public static final ResourceManagerReloadListener LISTENER = resourceManager -> {
POTION_ITEMS.clear();
FILLED_BUCKETS.clear();
};
}

View file

@ -1,147 +0,0 @@
package com.simibubi.create.content.contraptions.fluids.recipe;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler;
import com.simibubi.create.content.contraptions.processing.HeatCondition;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.brewing.BrewingRecipeRegistry;
import net.minecraftforge.common.brewing.IBrewingRecipe;
import net.minecraftforge.common.brewing.VanillaBrewingRecipe;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.ForgeRegistries;
public class PotionMixingRecipeManager {
public static Map<Item, List<MixingRecipe>> ALL = new HashMap<>();
public static List<MixingRecipe> getAllBrewingRecipes() {
List<MixingRecipe> mixingRecipes = new ArrayList<>();
// Vanilla
for (IBrewingRecipe iBrewingRecipe : BrewingRecipeRegistry.getRecipes()) {
if (!(iBrewingRecipe instanceof VanillaBrewingRecipe))
continue;
List<ItemStack> bottles = new ArrayList<>();
PotionBrewing.ALLOWED_CONTAINERS.forEach(i -> {
for (ItemStack itemStack : i.getItems())
bottles.add(itemStack);
});
Collection<ItemStack> reagents = getAllReagents(iBrewingRecipe);
Set<ItemStack> basicPotions = new HashSet<>();
for (Potion potion : ForgeRegistries.POTIONS.getValues()) {
if (potion == Potions.EMPTY)
continue;
for (ItemStack stack : bottles)
basicPotions.add(PotionUtils.setPotion(stack.copy(), potion));
}
Set<String> uniqueKeys = new HashSet<>();
List<ItemStack> potionFrontier = new ArrayList<>();
List<ItemStack> newPotions = new ArrayList<>();
potionFrontier.addAll(basicPotions);
int recipeIndex = 0;
while (!potionFrontier.isEmpty()) {
newPotions.clear();
for (ItemStack inputPotionStack : potionFrontier) {
Potion inputPotion = PotionUtils.getPotion(inputPotionStack);
for (ItemStack potionReagent : reagents) {
ItemStack outputPotionStack = iBrewingRecipe.getOutput(inputPotionStack.copy(), potionReagent);
if (outputPotionStack.isEmpty())
continue;
String uniqueKey = potionReagent.getItem()
.getRegistryName()
.toString() + "_"
+ inputPotion.getRegistryName()
.toString()
+ "_" + inputPotionStack.getItem()
.getRegistryName()
.toString();
if (!uniqueKeys.add(uniqueKey))
continue;
if (inputPotionStack.getItem() == outputPotionStack.getItem()) {
Potion outputPotion = PotionUtils.getPotion(outputPotionStack);
if (outputPotion == Potions.WATER)
continue;
}
FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(inputPotionStack);
FluidStack fluidFromPotionItem2 = PotionFluidHandler.getFluidFromPotionItem(outputPotionStack);
fluidFromPotionItem.setAmount(1000);
fluidFromPotionItem2.setAmount(1000);
MixingRecipe mixingRecipe = new ProcessingRecipeBuilder<>(MixingRecipe::new,
Create.asResource("potion_" + recipeIndex++)).require(Ingredient.of(potionReagent))
.require(FluidIngredient.fromFluidStack(fluidFromPotionItem))
.output(fluidFromPotionItem2)
.requiresHeat(HeatCondition.HEATED)
.build();
mixingRecipes.add(mixingRecipe);
newPotions.add(outputPotionStack);
}
}
potionFrontier.clear();
potionFrontier.addAll(newPotions);
}
break;
}
// TODO Modded brewing recipes?
return mixingRecipes;
}
public static Collection<ItemStack> getAllReagents(IBrewingRecipe recipe) {
return ForgeRegistries.ITEMS.getValues()
.stream()
.map(ItemStack::new)
.filter(recipe::isIngredient)
.collect(Collectors.toList());
}
public static final ResourceManagerReloadListener LISTENER = resourceManager -> {
ALL.clear();
getAllBrewingRecipes().forEach(recipe -> {
for (Ingredient ingredient : recipe.getIngredients()) {
for (ItemStack itemStack : ingredient.getItems()) {
ALL.computeIfAbsent(itemStack.getItem(), t -> new ArrayList<>())
.add(recipe);
return;
}
}
});
};
}

View file

@ -0,0 +1,141 @@
package com.simibubi.create.content.contraptions.fluids.recipe;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid.BottleType;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler;
import com.simibubi.create.content.contraptions.processing.HeatCondition;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionBrewing;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.brewing.BrewingRecipe;
import net.minecraftforge.common.brewing.BrewingRecipeRegistry;
import net.minecraftforge.common.brewing.IBrewingRecipe;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.ForgeRegistries;
public class PotionMixingRecipes {
public static final List<Item> SUPPORTED_CONTAINERS = List.of(Items.POTION, Items.SPLASH_POTION, Items.LINGERING_POTION);
public static final List<MixingRecipe> ALL = createRecipes();
public static final Map<Item, List<MixingRecipe>> BY_ITEM = sortRecipesByItem(ALL);
private static List<MixingRecipe> createRecipes() {
List<MixingRecipe> mixingRecipes = new ArrayList<>();
int recipeIndex = 0;
List<Item> allowedSupportedContainers = new ArrayList<>();
List<ItemStack> supportedContainerStacks = new ArrayList<>();
for (Item container : SUPPORTED_CONTAINERS) {
ItemStack stack = new ItemStack(container);
supportedContainerStacks.add(stack);
if (PotionBrewing.ALLOWED_CONTAINER.test(stack)) {
allowedSupportedContainers.add(container);
}
}
for (Item container : allowedSupportedContainers) {
BottleType bottleType = PotionFluidHandler.bottleTypeFromItem(container);
for (PotionBrewing.Mix<Potion> mix : PotionBrewing.POTION_MIXES) {
FluidStack fromFluid = PotionFluidHandler.getFluidFromPotion(mix.from.get(), bottleType, 1000);
FluidStack toFluid = PotionFluidHandler.getFluidFromPotion(mix.to.get(), bottleType, 1000);
mixingRecipes.add(createRecipe("potion_mixing_vanilla_" + recipeIndex++, mix.ingredient, fromFluid, toFluid));
}
}
for (PotionBrewing.Mix<Item> mix : PotionBrewing.CONTAINER_MIXES) {
Item from = mix.from.get();
if (!allowedSupportedContainers.contains(from)) {
continue;
}
Item to = mix.to.get();
if (!allowedSupportedContainers.contains(to)) {
continue;
}
BottleType fromBottleType = PotionFluidHandler.bottleTypeFromItem(from);
BottleType toBottleType = PotionFluidHandler.bottleTypeFromItem(to);
Ingredient ingredient = mix.ingredient;
for (Potion potion : ForgeRegistries.POTIONS.getValues()) {
if (potion == Potions.EMPTY) {
continue;
}
FluidStack fromFluid = PotionFluidHandler.getFluidFromPotion(potion, fromBottleType, 1000);
FluidStack toFluid = PotionFluidHandler.getFluidFromPotion(potion, toBottleType, 1000);
mixingRecipes.add(createRecipe("potion_mixing_vanilla_" + recipeIndex++, ingredient, fromFluid, toFluid));
}
}
recipeIndex = 0;
for (IBrewingRecipe recipe : BrewingRecipeRegistry.getRecipes()) {
if (recipe instanceof BrewingRecipe recipeImpl) {
ItemStack output = recipeImpl.getOutput();
if (!SUPPORTED_CONTAINERS.contains(output.getItem())) {
continue;
}
Ingredient input = recipeImpl.getInput();
Ingredient ingredient = recipeImpl.getIngredient();
FluidStack outputFluid = null;
for (ItemStack stack : supportedContainerStacks) {
if (input.test(stack)) {
FluidStack inputFluid = PotionFluidHandler.getFluidFromPotionItem(stack);
if (outputFluid == null) {
outputFluid = PotionFluidHandler.getFluidFromPotionItem(output);
}
mixingRecipes.add(createRecipe("potion_mixing_modded_" + recipeIndex++, ingredient, inputFluid, outputFluid));
}
}
}
}
return mixingRecipes;
}
private static MixingRecipe createRecipe(String id, Ingredient ingredient, FluidStack fromFluid, FluidStack toFluid) {
return new ProcessingRecipeBuilder<>(MixingRecipe::new,
Create.asResource(id)).require(ingredient)
.require(FluidIngredient.fromFluidStack(fromFluid))
.output(toFluid)
.requiresHeat(HeatCondition.HEATED)
.build();
}
private static Map<Item, List<MixingRecipe>> sortRecipesByItem(List<MixingRecipe> all) {
Map<Item, List<MixingRecipe>> byItem = new HashMap<>();
Set<Item> processedItems = new HashSet<>();
for (MixingRecipe recipe : all) {
for (Ingredient ingredient : recipe.getIngredients()) {
for (ItemStack itemStack : ingredient.getItems()) {
Item item = itemStack.getItem();
if (processedItems.add(item)) {
byItem.computeIfAbsent(item, i -> new ArrayList<>())
.add(recipe);
}
}
}
processedItems.clear();
}
return byItem;
}
}

View file

@ -16,7 +16,6 @@ import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.random.SimpleWeightedRandomList;
import net.minecraft.util.random.WeightedEntry.Wrapper;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@ -36,7 +35,6 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
@ -90,17 +88,15 @@ public class BlazeBurnerBlockItem extends BlockItem {
return super.useOn(context);
BaseSpawner spawner = ((SpawnerBlockEntity) te).getSpawner();
SimpleWeightedRandomList<SpawnData> spawnPotentials =
ObfuscationReflectionHelper.getPrivateValue(BaseSpawner.class, spawner, "f_45443_"); // spawnPotentials
List<SpawnData> possibleSpawns = spawnPotentials.unwrap()
List<SpawnData> possibleSpawns = spawner.spawnPotentials.unwrap()
.stream()
.map(Wrapper::getData)
.toList();
if (possibleSpawns.isEmpty()) {
possibleSpawns = new ArrayList<>();
possibleSpawns.add(ObfuscationReflectionHelper.getPrivateValue(BaseSpawner.class, spawner, "f_45444_")); // nextSpawnData
possibleSpawns.add(spawner.nextSpawnData);
}
ResourceLocation blazeId = EntityType.BLAZE.getRegistryName();

View file

@ -11,7 +11,6 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
@EventBusSubscriber
public class DivingBootsItem extends CopperArmorItem {
@ -27,7 +26,7 @@ public class DivingBootsItem extends CopperArmorItem {
return;
Vec3 motion = entity.getDeltaMovement();
Boolean isJumping = ObfuscationReflectionHelper.getPrivateValue(LivingEntity.class, entity, "f_20899_"); // jumping
boolean isJumping = entity.jumping;
entity.setOnGround(entity.isOnGround() || entity.verticalCollision);
if (isJumping && entity.isOnGround()) {

View file

@ -29,7 +29,6 @@ import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.common.crafting.MultiItemValue;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.items.ItemStackHandler;
public class BlueprintItem extends Item {
@ -92,8 +91,7 @@ public class BlueprintItem extends Item {
}
private static ItemStack convertIngredientToFilter(Ingredient ingredient) {
Ingredient.Value[] acceptedItems =
ObfuscationReflectionHelper.getPrivateValue(Ingredient.class, ingredient, "f_43902_"); // values
Ingredient.Value[] acceptedItems = ingredient.values;
if (acceptedItems == null || acceptedItems.length > 18)
return ItemStack.EMPTY;
if (acceptedItems.length == 0)

View file

@ -8,6 +8,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.foundation.item.CustomUseEffectsItem;
import com.simibubi.create.foundation.item.render.SimpleCustomRenderer;
import com.simibubi.create.foundation.mixin.accessor.LivingEntityAccessor;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.MethodsReturnNonnullByDefault;
@ -213,7 +214,7 @@ public class SandPaperItem extends Item implements CustomUseEffectsItem {
CompoundTag tag = stack.getOrCreateTag();
if (tag.contains("Polishing")) {
ItemStack polishing = ItemStack.of(tag.getCompound("Polishing"));
entity.spawnItemParticles(polishing, 1);
((LivingEntityAccessor) entity).create$callSpawnItemParticles(polishing, 1);
}
// After 6 ticks play the sound every 7th

View file

@ -9,12 +9,8 @@ import java.util.stream.Stream;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.Boat;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
@ -78,7 +74,7 @@ public class ItemRequirement {
if (block instanceof ISpecialBlockItemRequirement) {
baseRequirement = ((ISpecialBlockItemRequirement) block).getRequiredItems(state, te);
} else {
baseRequirement = ofBlockState(state, block);
baseRequirement = ofBlockState(state);
}
// Behaviours can add additional required items
@ -88,11 +84,14 @@ public class ItemRequirement {
return baseRequirement;
}
private static ItemRequirement ofBlockState(BlockState state, Block block) {
private static ItemRequirement ofBlockState(BlockState state) {
Block block = state.getBlock();
if (block == Blocks.AIR)
return NONE;
Item item = BlockItem.BY_BLOCK.getOrDefault(state.getBlock(), Items.AIR);
Item item = block.asItem();
if (item == Items.AIR)
return INVALID;
// double slab needs two items
if (state.hasProperty(BlockStateProperties.SLAB_TYPE) && state.getValue(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE)
@ -106,48 +105,33 @@ public class ItemRequirement {
if (block instanceof FarmBlock || block instanceof DirtPathBlock)
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(Items.DIRT)));
return item == Items.AIR ? INVALID : new ItemRequirement(ItemUseType.CONSUME, item);
return new ItemRequirement(ItemUseType.CONSUME, item);
}
public static ItemRequirement of(Entity entity) {
EntityType<?> type = entity.getType();
if (entity instanceof ISpecialEntityItemRequirement)
return ((ISpecialEntityItemRequirement) entity).getRequiredItems();
if (type == EntityType.ITEM_FRAME) {
ItemFrame ife = (ItemFrame) entity;
if (entity instanceof ItemFrame itemFrame) {
ItemStack frame = new ItemStack(Items.ITEM_FRAME);
ItemStack displayedItem = ife.getItem();
ItemStack displayedItem = itemFrame.getItem();
if (displayedItem.isEmpty())
return new ItemRequirement(ItemUseType.CONSUME, Items.ITEM_FRAME);
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(frame, displayedItem));
}
if (type == EntityType.PAINTING)
return new ItemRequirement(ItemUseType.CONSUME, Items.PAINTING);
if (type == EntityType.ARMOR_STAND) {
if (entity instanceof ArmorStand armorStand) {
List<ItemStack> requirements = new ArrayList<>();
ArmorStand armorStandEntity = (ArmorStand) entity;
armorStandEntity.getAllSlots().forEach(requirements::add);
requirements.add(new ItemStack(Items.ARMOR_STAND));
armorStand.getAllSlots().forEach(requirements::add);
return new ItemRequirement(ItemUseType.CONSUME, requirements);
}
if (entity instanceof AbstractMinecart) {
AbstractMinecart minecartEntity = (AbstractMinecart) entity;
return new ItemRequirement(ItemUseType.CONSUME, minecartEntity.getCartItem().getItem());
ItemStack pickedStack = entity.getPickResult();
if (pickedStack != null) {
return new ItemRequirement(ItemUseType.CONSUME, pickedStack);
}
if (entity instanceof Boat) {
Boat boatEntity = (Boat) entity;
return new ItemRequirement(ItemUseType.CONSUME, boatEntity.getDropItem());
}
if (type == EntityType.END_CRYSTAL)
return new ItemRequirement(ItemUseType.CONSUME, Items.END_CRYSTAL);
return INVALID;
}

View file

@ -8,6 +8,7 @@ import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkHolder;
@ -41,7 +42,6 @@ import net.minecraft.world.level.storage.WritableLevelData;
import net.minecraft.world.scores.Scoreboard;
import net.minecraft.world.ticks.BlackholeTickAccess;
import net.minecraft.world.ticks.LevelTickAccess;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class SchematicChunkSource extends ChunkSource {
private final Level fallbackWorld;
@ -92,7 +92,7 @@ public class SchematicChunkSource extends ChunkSource {
public static class EmptierChunk extends LevelChunk {
private static final class DummyLevel extends Level {
RegistryAccess access;
private RegistryAccess access;
private DummyLevel(WritableLevelData p_46450_, ResourceKey<Level> p_46451_, DimensionType p_46452_,
Supplier<ProfilerFiller> p_46453_, boolean p_46454_, boolean p_46455_, long p_46456_) {
@ -204,7 +204,8 @@ public class SchematicChunkSource extends ChunkSource {
}
private static final DummyLevel DUMMY_LEVEL = new DummyLevel(null, null,
ObfuscationReflectionHelper.getPrivateValue(DimensionType.class, null, "f_63848_"), null, false, false, 0);
RegistryAccess.builtin().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY).getOrThrow(DimensionType.OVERWORLD_LOCATION),
null, false, false, 0);
public EmptierChunk(RegistryAccess registryAccess) {
super(DUMMY_LEVEL.withAccess(registryAccess), null);

View file

@ -5,6 +5,7 @@ import java.util.Optional;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorItem;
import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock;
import com.simibubi.create.foundation.utility.BlockHelper;
@ -148,11 +149,10 @@ public abstract class LaunchedItem {
@Override
void place(Level world) {
// todo place belt
boolean isStart = state.getValue(BeltBlock.PART) == BeltPart.START;
BlockPos offset = BeltBlock.nextSegmentPosition(state, BlockPos.ZERO, isStart);
int i = length - 1;
Axis axis = state.getValue(BeltBlock.HORIZONTAL_FACING).getClockWise().getAxis();
Axis axis = state.getValue(BeltBlock.SLOPE) == BeltSlope.SIDEWAYS ? Axis.Y : state.getValue(BeltBlock.HORIZONTAL_FACING).getClockWise().getAxis();
world.setBlockAndUpdate(target, AllBlocks.SHAFT.getDefaultState().setValue(AbstractShaftBlock.AXIS, axis));
BeltConnectorItem
.createBelts(world, target, target.offset(offset.getX() * i, offset.getY() * i, offset.getZ() * i));

View file

@ -8,6 +8,8 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForBelt;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForBlockState;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForEntity;
import com.simibubi.create.foundation.render.CachedBufferer;
@ -165,18 +167,23 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
ms.mulPose(new Vector3f(1, 0, 0).rotationDegrees(360 * t));
ms.translate(-.125f, -.125f, -.125f);
// Render the Block
if (launched instanceof ForBlockState) {
// Render the Block
BlockState state;
if (launched instanceof ForBelt) {
// Render a shaft instead of the belt
state = AllBlocks.SHAFT.getDefaultState();
} else {
state = ((ForBlockState) launched).state;
}
float scale = .3f;
ms.scale(scale, scale, scale);
Minecraft.getInstance()
.getBlockRenderer()
.renderSingleBlock(((ForBlockState) launched).state, ms, buffer, light, overlay,
.renderSingleBlock(state, ms, buffer, light, overlay,
VirtualEmptyModelData.INSTANCE);
}
// Render the item
if (launched instanceof ForEntity) {
} else if (launched instanceof ForEntity) {
// Render the item
float scale = 1.2f;
ms.scale(scale, scale, scale);
Minecraft.getInstance()

View file

@ -32,6 +32,7 @@ import com.simibubi.create.foundation.utility.NBTProcessors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
@ -612,6 +613,8 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
return true;
if (state.getBlock() instanceof PistonHeadBlock)
return true;
if (AllBlocks.BELT.has(state))
return state.getValue(BeltBlock.PART) == BeltPart.MIDDLE;
return false;
}
@ -687,13 +690,17 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
}
public static BlockState stripBeltIfNotLast(BlockState blockState) {
BeltPart part = blockState.getValue(BeltBlock.PART);
if (part == BeltPart.MIDDLE)
return Blocks.AIR.defaultBlockState();
// is highest belt?
boolean isLastSegment = false;
Direction facing = blockState.getValue(BeltBlock.HORIZONTAL_FACING);
BeltSlope slope = blockState.getValue(BeltBlock.SLOPE);
boolean positive = facing.getAxisDirection() == AxisDirection.POSITIVE;
boolean start = blockState.getValue(BeltBlock.PART) == BeltPart.START;
boolean end = blockState.getValue(BeltBlock.PART) == BeltPart.END;
boolean start = part == BeltPart.START;
boolean end = part == BeltPart.END;
switch (slope) {
case DOWNWARD:
@ -702,17 +709,16 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
case UPWARD:
isLastSegment = end;
break;
case HORIZONTAL:
case VERTICAL:
default:
isLastSegment = positive && end || !positive && start;
}
if (!isLastSegment)
blockState = (blockState.getValue(BeltBlock.PART) == BeltPart.MIDDLE) ? Blocks.AIR.defaultBlockState()
: AllBlocks.SHAFT.getDefaultState()
.setValue(AbstractShaftBlock.AXIS, facing.getClockWise()
.getAxis());
return blockState;
if (isLastSegment)
return blockState;
return AllBlocks.SHAFT.getDefaultState()
.setValue(AbstractShaftBlock.AXIS, slope == BeltSlope.SIDEWAYS ? Axis.Y :
facing.getClockWise()
.getAxis());
}
protected void launchBlockOrBelt(BlockPos target, ItemStack icon, BlockState blockState, BlockEntity tile) {
@ -720,7 +726,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro
blockState = stripBeltIfNotLast(blockState);
if (tile instanceof BeltTileEntity && AllBlocks.BELT.has(blockState))
launchBelt(target, blockState, ((BeltTileEntity) tile).beltLength);
else
else if (blockState != Blocks.AIR.defaultBlockState())
launchBlock(target, icon, blockState, null);
} else {
CompoundTag data = null;

View file

@ -5,8 +5,6 @@ import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingPhysics;
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
import com.simibubi.create.content.contraptions.fluids.recipe.FluidTransferRecipes;
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
import com.simibubi.create.content.contraptions.wrench.WrenchItem;
import com.simibubi.create.content.curiosities.toolbox.ToolboxHandler;
import com.simibubi.create.content.curiosities.weapons.PotatoProjectileTypeManager;
@ -142,8 +140,6 @@ public class CommonEvents {
@SubscribeEvent
public static void addReloadListeners(AddReloadListenerEvent event) {
event.addListener(RecipeFinder.LISTENER);
event.addListener(PotionMixingRecipeManager.LISTENER);
event.addListener(FluidTransferRecipes.LISTENER);
event.addListener(PotatoProjectileTypeManager.ReloadListener.INSTANCE);
}

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.advancement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
@ -10,7 +11,6 @@ import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import com.google.common.collect.Sets;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@ -36,7 +36,7 @@ public abstract class StringSerializableTrigger<T> extends CriterionTriggerBase<
@SafeVarargs
public final Instance<T> forEntries(@Nullable T... entries) {
return new Instance<>(this, entries == null ? null : Sets.newHashSet(entries));
return new Instance<>(this, entries == null ? null : createLinkedHashSet(entries));
}
public void trigger(ServerPlayer player, @Nullable T registryEntry) {
@ -70,6 +70,12 @@ public abstract class StringSerializableTrigger<T> extends CriterionTriggerBase<
@Nullable
protected abstract String getKey(T value);
private static <T> LinkedHashSet<T> createLinkedHashSet(T[] elements) {
LinkedHashSet<T> set = new LinkedHashSet<>(elements.length);
Collections.addAll(set, elements);
return set;
}
public static class Instance<T> extends CriterionTriggerBase.Instance {
@Nullable

View file

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

View file

@ -1,6 +1,8 @@
package com.simibubi.create.foundation.block;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;
import com.tterrag.registrate.util.entry.BlockEntry;
@ -8,7 +10,7 @@ import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
public class DyedBlockList<T extends Block> {
public class DyedBlockList<T extends Block> implements Iterable<BlockEntry<T>> {
private static final int COLOR_AMOUNT = DyeColor.values().length;
@ -39,4 +41,24 @@ public class DyedBlockList<T extends Block> {
return (BlockEntry<T>[]) Arrays.copyOf(values, values.length);
}
@Override
public Iterator<BlockEntry<T>> iterator() {
return new Iterator<>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < values.length;
}
@SuppressWarnings("unchecked")
@Override
public BlockEntry<T> next() {
if (!hasNext())
throw new NoSuchElementException();
return (BlockEntry<T>) values[index++];
}
};
}
}

View file

@ -11,7 +11,6 @@ import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class FlySpeedCommand {
@ -35,8 +34,7 @@ public class FlySpeedCommand {
private static int sendFlySpeedUpdate(CommandContext<CommandSourceStack> ctx, ServerPlayer player, float speed) {
ClientboundPlayerAbilitiesPacket packet = new ClientboundPlayerAbilitiesPacket(player.getAbilities());
// packet.setFlySpeed(speed);
ObfuscationReflectionHelper.setPrivateValue(ClientboundPlayerAbilitiesPacket.class, packet, speed, "f_132663_"); // flyingSpeed
packet.flyingSpeed = speed;
player.connection.send(packet);
ctx.getSource()

View file

@ -0,0 +1,42 @@
package com.simibubi.create.foundation.data.recipe;
import static com.simibubi.create.foundation.data.recipe.Mods.EID;
import static com.simibubi.create.foundation.data.recipe.Mods.IE;
import static com.simibubi.create.foundation.data.recipe.Mods.INF;
import static com.simibubi.create.foundation.data.recipe.Mods.MEK;
import static com.simibubi.create.foundation.data.recipe.Mods.MW;
import static com.simibubi.create.foundation.data.recipe.Mods.SM;
import static com.simibubi.create.foundation.data.recipe.Mods.TH;
import com.simibubi.create.foundation.utility.Lang;
public enum CompatMetals {
ALUMINUM(IE, SM),
LEAD(MEK, TH, MW, IE, SM, EID),
NICKEL(TH, IE, SM),
OSMIUM(MEK),
PLATINUM(SM),
QUICKSILVER(MW),
SILVER(TH, MW, IE, SM, INF),
TIN(TH, MEK, MW, SM),
URANIUM(MEK, IE, SM);
private final Mods[] mods;
private final String name;
CompatMetals(Mods... mods) {
this.name = Lang.asId(name());
this.mods = mods;
}
public String getName() {
return name;
}
/**
* These mods must provide an ingot and nugget variant of the corresponding metal.
*/
public Mods[] getMods() {
return mods;
}
}

View file

@ -1,5 +1,15 @@
package com.simibubi.create.foundation.data.recipe;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.NICKEL;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.OSMIUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.PLATINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.QUICKSILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.SILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.TIN;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.URANIUM;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@ -93,30 +103,30 @@ public class CrushingRecipeGen extends ProcessingRecipeGen {
RAW_IRON_ORE = rawOre(() -> Items.RAW_IRON, AllItems.CRUSHED_IRON::get, 1),
RAW_GOLD_ORE = rawOre(() -> Items.RAW_GOLD, AllItems.CRUSHED_GOLD::get, 1),
OSMIUM_RAW_ORE = moddedRawOre("osmium", AllItems.CRUSHED_OSMIUM::get, 1),
PLATINUM_RAW_ORE = moddedRawOre("platinum", AllItems.CRUSHED_PLATINUM::get, 1),
SILVER_RAW_ORE = moddedRawOre("silver", AllItems.CRUSHED_SILVER::get, 1),
TIN_RAW_ORE = moddedRawOre("tin", AllItems.CRUSHED_TIN::get, 1),
QUICKSILVER_RAW_ORE = moddedRawOre("quicksilver", AllItems.CRUSHED_QUICKSILVER::get, 1),
LEAD_RAW_ORE = moddedRawOre("lead", AllItems.CRUSHED_LEAD::get, 1),
ALUMINUM_RAW_ORE = moddedRawOre("aluminum", AllItems.CRUSHED_BAUXITE::get, 1),
URANIUM_RAW_ORE = moddedRawOre("uranium", AllItems.CRUSHED_URANIUM::get, 1),
NICKEL_RAW_ORE = moddedRawOre("nickel", AllItems.CRUSHED_NICKEL::get, 1),
OSMIUM_RAW_ORE = moddedRawOre(OSMIUM, AllItems.CRUSHED_OSMIUM::get, 1),
PLATINUM_RAW_ORE = moddedRawOre(PLATINUM, AllItems.CRUSHED_PLATINUM::get, 1),
SILVER_RAW_ORE = moddedRawOre(SILVER, AllItems.CRUSHED_SILVER::get, 1),
TIN_RAW_ORE = moddedRawOre(TIN, AllItems.CRUSHED_TIN::get, 1),
QUICKSILVER_RAW_ORE = moddedRawOre(QUICKSILVER, AllItems.CRUSHED_QUICKSILVER::get, 1),
LEAD_RAW_ORE = moddedRawOre(LEAD, AllItems.CRUSHED_LEAD::get, 1),
ALUMINUM_RAW_ORE = moddedRawOre(ALUMINUM, AllItems.CRUSHED_BAUXITE::get, 1),
URANIUM_RAW_ORE = moddedRawOre(URANIUM, AllItems.CRUSHED_URANIUM::get, 1),
NICKEL_RAW_ORE = moddedRawOre(NICKEL, AllItems.CRUSHED_NICKEL::get, 1),
RAW_COPPER_BLOCK = rawOre(() -> Items.RAW_COPPER_BLOCK,AllItems.CRUSHED_COPPER::get, 9),
RAW_ZINC_BLOCK = rawOre(AllBlocks.RAW_ZINC_BLOCK::get, AllItems.CRUSHED_ZINC::get, 9),
RAW_IRON_BLOCK = rawOre(() -> Items.RAW_IRON_BLOCK, AllItems.CRUSHED_IRON::get, 9),
RAW_GOLD_BLOCK = rawOre(() -> Items.RAW_GOLD_BLOCK, AllItems.CRUSHED_GOLD::get, 9),
OSMIUM_RAW_BLOCK = moddedRawOre("osmium", AllItems.CRUSHED_OSMIUM::get, 9),
PLATINUM_RAW_BLOCK = moddedRawOre("platinum", AllItems.CRUSHED_PLATINUM::get, 9),
SILVER_RAW_BLOCK = moddedRawOre("silver", AllItems.CRUSHED_SILVER::get, 9),
TIN_RAW_BLOCK = moddedRawOre("tin", AllItems.CRUSHED_TIN::get, 9),
QUICKSILVER_RAW_BLOCK = moddedRawOre("quicksilver", AllItems.CRUSHED_QUICKSILVER::get, 9),
LEAD_RAW_BLOCK = moddedRawOre("lead", AllItems.CRUSHED_LEAD::get, 9),
ALUMINUM_RAW_BLOCK = moddedRawOre("aluminum", AllItems.CRUSHED_BAUXITE::get, 9),
URANIUM_RAW_BLOCK = moddedRawOre("uranium", AllItems.CRUSHED_URANIUM::get, 9),
NICKEL_RAW_BLOCK = moddedRawOre("nickel", AllItems.CRUSHED_NICKEL::get, 9),
OSMIUM_RAW_BLOCK = moddedRawOre(OSMIUM, AllItems.CRUSHED_OSMIUM::get, 9),
PLATINUM_RAW_BLOCK = moddedRawOre(PLATINUM, AllItems.CRUSHED_PLATINUM::get, 9),
SILVER_RAW_BLOCK = moddedRawOre(SILVER, AllItems.CRUSHED_SILVER::get, 9),
TIN_RAW_BLOCK = moddedRawOre(TIN, AllItems.CRUSHED_TIN::get, 9),
QUICKSILVER_RAW_BLOCK = moddedRawOre(QUICKSILVER, AllItems.CRUSHED_QUICKSILVER::get, 9),
LEAD_RAW_BLOCK = moddedRawOre(LEAD, AllItems.CRUSHED_LEAD::get, 9),
ALUMINUM_RAW_BLOCK = moddedRawOre(ALUMINUM, AllItems.CRUSHED_BAUXITE::get, 9),
URANIUM_RAW_BLOCK = moddedRawOre(URANIUM, AllItems.CRUSHED_URANIUM::get, 9),
NICKEL_RAW_BLOCK = moddedRawOre(NICKEL, AllItems.CRUSHED_NICKEL::get, 9),
NETHER_WART = create("nether_wart_block", b -> b.duration(150)
.require(Blocks.NETHER_WART_BLOCK)
@ -211,8 +221,9 @@ public class CrushingRecipeGen extends ProcessingRecipeGen {
.output(result.get(), amount)
.output(.75f, AllItems.EXP_NUGGET.get(), amount));
}
protected GeneratedRecipe moddedRawOre(String name, Supplier<ItemLike> result, int amount) {
protected GeneratedRecipe moddedRawOre(CompatMetals metal, Supplier<ItemLike> result, int amount) {
String name = metal.getName();
return create("raw_" + name + (amount == 1 ? "_ore" : "_block"), b -> {
String prefix = amount == 1 ? "raw_ores/" : "raw_blocks/";
return b.duration(400)
@ -222,9 +233,9 @@ public class CrushingRecipeGen extends ProcessingRecipeGen {
.output(.75f, AllItems.EXP_NUGGET.get(), amount);
});
}
public CrushingRecipeGen(DataGenerator p_i48262_1_) {
super(p_i48262_1_);
public CrushingRecipeGen(DataGenerator dataGenerator) {
super(dataGenerator);
}
@Override

View file

@ -14,8 +14,8 @@ public enum Mods {
;
private String id;
private boolean reversedPrefix;
private final String id;
private final boolean reversedPrefix;
private Mods(String id, boolean reversedPrefix) {
this.id = id;
@ -24,11 +24,11 @@ public enum Mods {
public ResourceLocation ingotOf(String type) {
return new ResourceLocation(id, reversedPrefix ? "ingot_" + type : type + "_ingot");
}
public ResourceLocation nuggetOf(String type) {
return new ResourceLocation(id, reversedPrefix ? "nugget_" + type : type + "_nugget");
}
public ResourceLocation oreOf(String type) {
return new ResourceLocation(id, reversedPrefix ? "ore_" + type : type + "_ore");
}
@ -36,9 +36,9 @@ public enum Mods {
public ResourceLocation deepslateOreOf(String type) {
return new ResourceLocation(id, reversedPrefix ? "deepslate_ore_" + type : "deepslate_" + type + "_ore");
}
public String getId() {
return id;
}
}

View file

@ -1,12 +1,14 @@
package com.simibubi.create.foundation.data.recipe;
import static com.simibubi.create.foundation.data.recipe.Mods.EID;
import static com.simibubi.create.foundation.data.recipe.Mods.IE;
import static com.simibubi.create.foundation.data.recipe.Mods.INF;
import static com.simibubi.create.foundation.data.recipe.Mods.MEK;
import static com.simibubi.create.foundation.data.recipe.Mods.MW;
import static com.simibubi.create.foundation.data.recipe.Mods.SM;
import static com.simibubi.create.foundation.data.recipe.Mods.TH;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.NICKEL;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.OSMIUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.PLATINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.QUICKSILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.SILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.TIN;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.URANIUM;
import java.util.ArrayList;
import java.util.List;
@ -1023,15 +1025,15 @@ public class StandardRecipeGen extends CreateRecipeProvider {
CRUSHED_COPPER = blastCrushedMetal(() -> Items.COPPER_INGOT, AllItems.CRUSHED_COPPER::get),
CRUSHED_ZINC = blastCrushedMetal(AllItems.ZINC_INGOT::get, AllItems.CRUSHED_ZINC::get),
CRUSHED_OSMIUM = blastModdedCrushedMetal(AllItems.CRUSHED_OSMIUM, "osmium", MEK),
CRUSHED_PLATINUM = blastModdedCrushedMetal(AllItems.CRUSHED_PLATINUM, "platinum", SM),
CRUSHED_SILVER = blastModdedCrushedMetal(AllItems.CRUSHED_SILVER, "silver", MW, TH, IE, SM, INF),
CRUSHED_TIN = blastModdedCrushedMetal(AllItems.CRUSHED_TIN, "tin", MEK, TH, MW, SM),
CRUSHED_LEAD = blastModdedCrushedMetal(AllItems.CRUSHED_LEAD, "lead", MEK, MW, TH, IE, SM, EID),
CRUSHED_QUICKSILVER = blastModdedCrushedMetal(AllItems.CRUSHED_QUICKSILVER, "quicksilver", MW),
CRUSHED_BAUXITE = blastModdedCrushedMetal(AllItems.CRUSHED_BAUXITE, "aluminum", IE, SM),
CRUSHED_URANIUM = blastModdedCrushedMetal(AllItems.CRUSHED_URANIUM, "uranium", MEK, IE, SM),
CRUSHED_NICKEL = blastModdedCrushedMetal(AllItems.CRUSHED_NICKEL, "nickel", TH, IE, SM),
CRUSHED_OSMIUM = blastModdedCrushedMetal(AllItems.CRUSHED_OSMIUM, OSMIUM),
CRUSHED_PLATINUM = blastModdedCrushedMetal(AllItems.CRUSHED_PLATINUM, PLATINUM),
CRUSHED_SILVER = blastModdedCrushedMetal(AllItems.CRUSHED_SILVER, SILVER),
CRUSHED_TIN = blastModdedCrushedMetal(AllItems.CRUSHED_TIN, TIN),
CRUSHED_LEAD = blastModdedCrushedMetal(AllItems.CRUSHED_LEAD, LEAD),
CRUSHED_QUICKSILVER = blastModdedCrushedMetal(AllItems.CRUSHED_QUICKSILVER, QUICKSILVER),
CRUSHED_BAUXITE = blastModdedCrushedMetal(AllItems.CRUSHED_BAUXITE, ALUMINUM),
CRUSHED_URANIUM = blastModdedCrushedMetal(AllItems.CRUSHED_URANIUM, URANIUM),
CRUSHED_NICKEL = blastModdedCrushedMetal(AllItems.CRUSHED_NICKEL, NICKEL),
ZINC_ORE = create(AllItems.ZINC_INGOT::get).withSuffix("_from_ore")
.viaCookingTag(() -> AllTags.forgeItemTag("ores/zinc"))
@ -1089,8 +1091,9 @@ public class StandardRecipeGen extends CreateRecipeProvider {
.inBlastFurnace();
}
GeneratedRecipe blastModdedCrushedMetal(ItemEntry<? extends Item> ingredient, String metalName, Mods... mods) {
for (Mods mod : mods) {
GeneratedRecipe blastModdedCrushedMetal(ItemEntry<? extends Item> ingredient, CompatMetals metal) {
String metalName = metal.getName();
for (Mods mod : metal.getMods()) {
ResourceLocation ingot = mod.ingotOf(metalName);
String modId = mod.getId();
create(ingot).withSuffix("_compat_" + modId)

View file

@ -1,12 +1,14 @@
package com.simibubi.create.foundation.data.recipe;
import static com.simibubi.create.foundation.data.recipe.Mods.EID;
import static com.simibubi.create.foundation.data.recipe.Mods.IE;
import static com.simibubi.create.foundation.data.recipe.Mods.INF;
import static com.simibubi.create.foundation.data.recipe.Mods.MEK;
import static com.simibubi.create.foundation.data.recipe.Mods.MW;
import static com.simibubi.create.foundation.data.recipe.Mods.SM;
import static com.simibubi.create.foundation.data.recipe.Mods.TH;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.ALUMINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.LEAD;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.NICKEL;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.OSMIUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.PLATINUM;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.QUICKSILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.SILVER;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.TIN;
import static com.simibubi.create.foundation.data.recipe.CompatMetals.URANIUM;
import java.util.function.Supplier;
@ -50,15 +52,15 @@ public class WashingRecipeGen extends ProcessingRecipeGen {
CRUSHED_GOLD = crushedOre(AllItems.CRUSHED_GOLD, () -> Items.GOLD_NUGGET, () -> Items.QUARTZ, .5f),
CRUSHED_IRON = crushedOre(AllItems.CRUSHED_IRON, () -> Items.IRON_NUGGET, () -> Items.REDSTONE, .125f),
CRUSHED_OSMIUM = moddedCrushedOre(AllItems.CRUSHED_OSMIUM, "osmium", MEK),
CRUSHED_PLATINUM = moddedCrushedOre(AllItems.CRUSHED_PLATINUM, "platinum", SM),
CRUSHED_SILVER = moddedCrushedOre(AllItems.CRUSHED_SILVER, "silver", TH, MW, IE, SM, INF),
CRUSHED_TIN = moddedCrushedOre(AllItems.CRUSHED_TIN, "tin", TH, MEK, MW, SM),
CRUSHED_LEAD = moddedCrushedOre(AllItems.CRUSHED_LEAD, "lead", MEK, TH, MW, IE, SM, EID),
CRUSHED_QUICKSILVER = moddedCrushedOre(AllItems.CRUSHED_QUICKSILVER, "quicksilver", MW),
CRUSHED_BAUXITE = moddedCrushedOre(AllItems.CRUSHED_BAUXITE, "aluminum", IE, SM),
CRUSHED_URANIUM = moddedCrushedOre(AllItems.CRUSHED_URANIUM, "uranium", MEK, IE, SM),
CRUSHED_NICKEL = moddedCrushedOre(AllItems.CRUSHED_NICKEL, "nickel", TH, IE, SM),
CRUSHED_OSMIUM = moddedCrushedOre(AllItems.CRUSHED_OSMIUM, OSMIUM),
CRUSHED_PLATINUM = moddedCrushedOre(AllItems.CRUSHED_PLATINUM, PLATINUM),
CRUSHED_SILVER = moddedCrushedOre(AllItems.CRUSHED_SILVER, SILVER),
CRUSHED_TIN = moddedCrushedOre(AllItems.CRUSHED_TIN, TIN),
CRUSHED_LEAD = moddedCrushedOre(AllItems.CRUSHED_LEAD, LEAD),
CRUSHED_QUICKSILVER = moddedCrushedOre(AllItems.CRUSHED_QUICKSILVER, QUICKSILVER),
CRUSHED_BAUXITE = moddedCrushedOre(AllItems.CRUSHED_BAUXITE, ALUMINUM),
CRUSHED_URANIUM = moddedCrushedOre(AllItems.CRUSHED_URANIUM, URANIUM),
CRUSHED_NICKEL = moddedCrushedOre(AllItems.CRUSHED_NICKEL, NICKEL),
ICE = convert(Blocks.ICE, Blocks.PACKED_ICE), MAGMA_BLOCK = convert(Blocks.MAGMA_BLOCK, Blocks.OBSIDIAN),
@ -93,8 +95,9 @@ public class WashingRecipeGen extends ProcessingRecipeGen {
.output(secondaryChance, secondary.get(), 1));
}
public GeneratedRecipe moddedCrushedOre(ItemEntry<? extends Item> crushed, String metalName, Mods... mods) {
for (Mods mod : mods) {
public GeneratedRecipe moddedCrushedOre(ItemEntry<? extends Item> crushed, CompatMetals metal) {
String metalName = metal.getName();
for (Mods mod : metal.getMods()) {
ResourceLocation nugget = mod.nuggetOf(metalName);
create(mod.getId() + "/" + crushed.getId()
.getPath(),
@ -105,8 +108,8 @@ public class WashingRecipeGen extends ProcessingRecipeGen {
return null;
}
public WashingRecipeGen(DataGenerator p_i48262_1_) {
super(p_i48262_1_);
public WashingRecipeGen(DataGenerator dataGenerator) {
super(dataGenerator);
}
@Override

View file

@ -26,7 +26,6 @@ import net.minecraft.client.renderer.PanoramaRenderer;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class CreateMainMenuScreen extends AbstractSimiScreen {
@ -50,9 +49,8 @@ public class CreateMainMenuScreen extends AbstractSimiScreen {
public CreateMainMenuScreen(Screen parent) {
this.parent = parent;
returnOnClose = true;
if (parent instanceof TitleScreen)
vanillaPanorama = ObfuscationReflectionHelper.getPrivateValue(TitleScreen.class, (TitleScreen) parent,
"f_96729_"); // panorama
if (parent instanceof TitleScreen titleScreen)
vanillaPanorama = titleScreen.panorama;
else
vanillaPanorama = new PanoramaRenderer(TitleScreen.CUBE_MAP);
}

View file

@ -12,15 +12,15 @@ public class TagDependentIngredientItem extends Item {
private ResourceLocation tag;
public TagDependentIngredientItem(Properties p_i48487_1_, ResourceLocation tag) {
super(p_i48487_1_);
public TagDependentIngredientItem(Properties properties, ResourceLocation tag) {
super(properties);
this.tag = tag;
}
@Override
public void fillItemCategory(CreativeModeTab p_150895_1_, NonNullList<ItemStack> p_150895_2_) {
public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> list) {
if (!shouldHide())
super.fillItemCategory(p_150895_1_, p_150895_2_);
super.fillItemCategory(tab, list);
}
public boolean shouldHide() {

View file

@ -0,0 +1,22 @@
package com.simibubi.create.foundation.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.core.Position;
import net.minecraft.core.dispenser.AbstractProjectileDispenseBehavior;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
@Mixin(AbstractProjectileDispenseBehavior.class)
public interface AbstractProjectileDispenseBehaviorAccessor {
@Invoker("getProjectile")
Projectile create$callGetProjectile(Level level, Position position, ItemStack stack);
@Invoker("getUncertainty")
float create$callGetUncertainty();
@Invoker("getPower")
float create$callGetPower();
}

View file

@ -0,0 +1,13 @@
package com.simibubi.create.foundation.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.GameRenderer;
@Mixin(GameRenderer.class)
public interface GameRendererAccessor {
@Invoker("getFov")
double create$callGetFov(Camera camera, float partialTicks, boolean useFOVSetting);
}

View file

@ -0,0 +1,13 @@
package com.simibubi.create.foundation.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
@Mixin(LivingEntity.class)
public interface LivingEntityAccessor {
@Invoker("spawnItemParticles")
void create$callSpawnItemParticles(ItemStack stack, int count);
}

View file

@ -0,0 +1,17 @@
package com.simibubi.create.foundation.mixin.accessor;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.client.particle.ParticleEngine;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.resources.ResourceLocation;
@Mixin(ParticleEngine.class)
public interface ParticleEngineAccessor {
// This field cannot be ATed because its type is patched by Forge
@Accessor("providers")
Map<ResourceLocation, ParticleProvider<?>> create$getProviders();
}

View file

@ -14,6 +14,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.content.schematics.SchematicWorld;
import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor;
import com.simibubi.create.foundation.ponder.element.WorldSectionElement;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.tileEntity.IMultiTileContainer;
@ -24,7 +25,6 @@ import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleEngine;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
@ -47,7 +47,6 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.registries.ForgeRegistries;
public class PonderWorld extends SchematicWorld {
@ -61,7 +60,7 @@ public class PonderWorld extends SchematicWorld {
private Supplier<ClientLevel> asClientWorld = Suppliers.memoize(() -> WrappedClientWorld.of(this));
protected PonderWorldParticles particles;
private final Map<ResourceLocation, ParticleProvider<?>> particleFactories;
private final Map<ResourceLocation, ParticleProvider<?>> particleProviders;
int overrideLight;
Selection mask;
@ -73,10 +72,7 @@ public class PonderWorld extends SchematicWorld {
blockBreakingProgressions = new HashMap<>();
originalEntities = new ArrayList<>();
particles = new PonderWorldParticles(this);
// ParticleManager.factories - ATs don't seem to like this one
particleFactories = ObfuscationReflectionHelper.getPrivateValue(ParticleEngine.class,
Minecraft.getInstance().particleEngine, "f_107293_"); // providers
particleProviders = ((ParticleEngineAccessor) Minecraft.getInstance().particleEngine).create$getProviders();
}
public void createBackup() {
@ -233,9 +229,9 @@ public class PonderWorld extends SchematicWorld {
private <T extends ParticleOptions> Particle makeParticle(T data, double x, double y, double z, double mx, double my,
double mz) {
ResourceLocation key = ForgeRegistries.PARTICLE_TYPES.getKey(data.getType());
ParticleProvider<T> iparticlefactory = (ParticleProvider<T>) particleFactories.get(key);
return iparticlefactory == null ? null
: iparticlefactory.createParticle(data, asClientWorld.get(), x, y, z, mx, my, mz);
ParticleProvider<T> particleProvider = (ParticleProvider<T>) particleProviders.get(key);
return particleProvider == null ? null
: particleProvider.createParticle(data, asClientWorld.get(), x, y, z, mx, my, mz);
}
@Override

View file

@ -6,6 +6,7 @@ import javax.annotation.Nullable;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import com.simibubi.create.foundation.mixin.accessor.GameRendererAccessor;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
@ -242,7 +243,7 @@ public class VecHelper {
}
// ----- adjust for fov -----
float fov = (float) mc.gameRenderer.getFov(ari, partialTicks, true);
float fov = (float) ((GameRendererAccessor) mc.gameRenderer).create$callGetFov(ari, partialTicks, true);
float half_height = (float) mc.getWindow()
.getGuiScaledHeight() / 2;

View file

@ -8,7 +8,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@ -24,10 +23,8 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.ticks.LevelTicks;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@ -36,7 +33,7 @@ public class WrappedServerWorld extends ServerLevel {
protected Level world;
public WrappedServerWorld(Level world) {
super(world.getServer(), Util.backgroundExecutor(), getLevelSaveFromWorld(world),
super(world.getServer(), Util.backgroundExecutor(), world.getServer().storageSource,
(ServerLevelData) world.getLevelData(), world.dimension(), world.dimensionType(),
new DummyStatusListener(), ((ServerChunkCache) world.getChunkSource()).getGenerator(), world.isDebug(),
world.getBiomeManager().biomeZoomSeed, Collections.emptyList(), false);
@ -130,8 +127,4 @@ public class WrappedServerWorld extends ServerLevel {
public Biome getUncachedNoiseBiome(int p_225604_1_, int p_225604_2_, int p_225604_3_) {
return world.getUncachedNoiseBiome(p_225604_1_, p_225604_2_, p_225604_3_);
}
private static LevelStorageSource.LevelStorageAccess getLevelSaveFromWorld(Level world) {
return ObfuscationReflectionHelper.getPrivateValue(MinecraftServer.class, world.getServer(), "f_129744_"); // storageSource
}
}

View file

@ -1,41 +1,32 @@
public net.minecraft.server.network.ServerGamePacketListenerImpl f_9737_ # aboveGroundTickCount
public net.minecraft.client.multiplayer.ClientPacketListener f_104897_ # serverChunkRadius
# For CubeParticle
protected net.minecraft.client.particle.Particle f_107205_ # stoppedByCollision
# ChunkStatus
public-f net.minecraft.world.level.chunk.ChunkStatus f_62326_ # FULL
# PotionBrewing
public net.minecraft.world.item.alchemy.PotionBrewing f_43496_ # ALLOWED_CONTAINERS
public net.minecraft.client.gui.Font m_92863_(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/gui/font/FontSet; # getFontSet
protected net.minecraft.world.entity.Entity m_19956_(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity$MoveFunction;)V # positionRider
public net.minecraft.world.level.biome.BiomeManager f_47863_ # biomeZoomSeed
public net.minecraft.client.renderer.entity.ItemRenderer f_115096_ # textureManager
# BeaconBlockEntity
public net.minecraft.world.level.block.entity.BeaconBlockEntity f_58648_ # beamSections
# ServerTickList (For stopping placed fluids from spilling)
public net.minecraft.world.level.ServerTickList f_47209_ # tickNextTickSet
public net.minecraft.world.level.ServerTickList f_47210_ # tickNextTickList
public net.minecraft.client.Minecraft f_91013_ # pausePartialTick
# GameRenderer
public net.minecraft.client.renderer.GameRenderer m_109141_(Lnet/minecraft/client/Camera;FZ)D # getFov
# ItemInHandRenderer
public net.minecraft.client.gui.Font m_92863_(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/gui/font/FontSet; # getFontSet
public net.minecraft.client.gui.screens.TitleScreen f_96729_ # panorama
public net.minecraft.client.multiplayer.ClientPacketListener f_104897_ # serverChunkRadius
protected net.minecraft.client.particle.Particle f_107205_ # stoppedByCollision
public net.minecraft.client.renderer.ItemInHandRenderer f_109300_ # mainHandItem
public net.minecraft.client.renderer.ItemInHandRenderer f_109301_ # offHandItem
public net.minecraft.client.renderer.entity.ItemRenderer f_115096_ # textureManager
# PaletteResize
public net.minecraft.world.level.chunk.HashMapPalette f_62658_ # values
public net.minecraft.world.level.chunk.PaletteResize
public-f net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket f_132663_ # flyingSpeed
public net.minecraft.world.entity.LivingEntity m_21060_(Lnet/minecraft/world/item/ItemStack;I)V # spawnItemParticles
public net.minecraft.server.MinecraftServer f_129744_ # storageSource
public net.minecraft.server.network.ServerGamePacketListenerImpl f_9737_ # aboveGroundTickCount
public net.minecraft.world.entity.Entity f_146795_ # removalReason
protected net.minecraft.world.entity.Entity m_19956_(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity$MoveFunction;)V # positionRider
public net.minecraft.world.entity.LivingEntity f_20899_ # jumping
public-f net.minecraft.world.item.HoneycombItem f_150863_ # WAXABLES
public net.minecraft.world.item.alchemy.PotionBrewing f_43494_ # POTION_MIXES
public net.minecraft.world.item.alchemy.PotionBrewing f_43495_ # CONTAINER_MIXES
public net.minecraft.world.item.alchemy.PotionBrewing f_43497_ # ALLOWED_CONTAINER
public net.minecraft.world.item.crafting.Ingredient f_43902_ # values
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_45444_ # nextSpawnData
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.chunk.HashMapPalette f_62658_ # values
public net.minecraft.world.level.chunk.PaletteResize

View file

@ -5,7 +5,9 @@
"compatibilityLevel": "JAVA_16",
"refmap": "create.refmap.json",
"mixins": [
"CustomItemUseEffectsMixin"
"CustomItemUseEffectsMixin",
"accessor.AbstractProjectileDispenseBehaviorAccessor",
"accessor.LivingEntityAccessor"
],
"client": [
"DestroyProgressMixin",
@ -13,7 +15,9 @@
"FixNormalScalingMixin",
"HeavyBootsOnPlayerMixin",
"ModelDataRefreshMixin",
"WindowResizeMixin"
"WindowResizeMixin",
"accessor.GameRendererAccessor",
"accessor.ParticleEngineAccessor"
],
"injectors": {
"defaultRequire": 1

View file

@ -0,0 +1,56 @@
{
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "upgrade_aquatic"
}
],
"type": "minecraft:crafting_shapeless",
"ingredients": [
{
"tag": "minecraft:small_flowers"
},
{
"tag": "minecraft:small_flowers"
},
[
{
"item": "upgrade_aquatic:acan_coral"
},
{
"item": "upgrade_aquatic:finger_coral"
},
{
"item": "upgrade_aquatic:star_coral"
},
{
"item": "upgrade_aquatic:moss_coral"
},
{
"item": "upgrade_aquatic:petal_coral"
},
{
"item": "upgrade_aquatic:branch_coral"
},
{
"item": "upgrade_aquatic:rock_coral"
},
{
"item": "upgrade_aquatic:pillow_coral"
},
{
"item": "upgrade_aquatic:chrome_coral"
},
{
"item": "upgrade_aquatic:silk_coral"
}
],
{
"item": "minecraft:bone_meal"
}
],
"result": {
"item": "create:tree_fertilizer",
"count": 2
}
}