Merge branch 'refs/heads/mc1.20.1/dev' into mc1.20.1/mmc-5

# Conflicts:
#	src/generated/resources/.cache/b256105d8411632b0d585496ea8944a751a08034
This commit is contained in:
attack8 2025-01-28 07:30:19 -05:00
commit 5ee0eca59e
41 changed files with 233 additions and 98 deletions

View file

@ -25,7 +25,7 @@ registrate_version = MC1.20-1.3.3
flywheel_minecraft_version = 1.20.1 flywheel_minecraft_version = 1.20.1
flywheel_version = 1.0.0-beta-145 flywheel_version = 1.0.0-beta-145
jei_minecraft_version = 1.20.1 jei_minecraft_version = 1.20.1
jei_version = 15.10.0.39 jei_version = 15.19.0.85
curios_minecraft_version = 1.20.1 curios_minecraft_version = 1.20.1
curios_version = 5.3.1 curios_version = 5.3.1

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-10-11T10:29:49.10689745 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] // 1.20.1 2025-01-04T09:59:54.9600791 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json 60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json 6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json
c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json
@ -4185,6 +4185,7 @@ a5874f73c7dc0a3ae12999e6ae8abf45bc7fb9be data/create/tags/blocks/passive_boiler_
9bc8c13fd80bdbe7f767b91ee1a1042e9aff02b0 data/create/tags/blocks/roots.json 9bc8c13fd80bdbe7f767b91ee1a1042e9aff02b0 data/create/tags/blocks/roots.json
79ed9149ee2ce143114db4ccafda8a2b6a293aac data/create/tags/blocks/safe_nbt.json 79ed9149ee2ce143114db4ccafda8a2b6a293aac data/create/tags/blocks/safe_nbt.json
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json 79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json
f02fc9781e8f0ae33ed3b98cf4f46ba6927c7ff8 data/create/tags/blocks/sugar_cane_variants.json
5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json 5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json
2589b135c0e96ad29076569e144528fe32ea5b39 data/create/tags/blocks/tracks.json 2589b135c0e96ad29076569e144528fe32ea5b39 data/create/tags/blocks/tracks.json
1b6977d9a399cf6ee042e3f8f5e64e4d3cda5489 data/create/tags/blocks/tree_attachments.json 1b6977d9a399cf6ee042e3f8f5e64e4d3cda5489 data/create/tags/blocks/tree_attachments.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-06T15:13:15.0209174 Create's Processing Recipes // 1.20.1 2024-12-15T23:26:23.3573034 Create's Processing Recipes
3c94326fb730f68c1e44fe1e2ef09c9db6ffd92b data/create/recipes/compacting/andesite_from_flint.json 3c94326fb730f68c1e44fe1e2ef09c9db6ffd92b data/create/recipes/compacting/andesite_from_flint.json
8d3d5b31f3601b9f681ff710e0545a483a1494c6 data/create/recipes/compacting/blaze_cake.json 8d3d5b31f3601b9f681ff710e0545a483a1494c6 data/create/recipes/compacting/blaze_cake.json
8bd7f4e3a686ab520b2d55594d2018d0e9a50c91 data/create/recipes/compacting/chocolate.json 8bd7f4e3a686ab520b2d55594d2018d0e9a50c91 data/create/recipes/compacting/chocolate.json
@ -814,7 +814,7 @@ d480b1b4c48440c6d6cb775321e95be7ea171aa5 data/create/recipes/milling/andesite.js
a3b4a9eb3970eea745dff83c2d5fbab403ed481f data/create/recipes/milling/blue_orchid.json a3b4a9eb3970eea745dff83c2d5fbab403ed481f data/create/recipes/milling/blue_orchid.json
720ff9753bb30e874483fc850c3cbc8bfa973224 data/create/recipes/milling/bone.json 720ff9753bb30e874483fc850c3cbc8bfa973224 data/create/recipes/milling/bone.json
e84433fe6ec772c212d20109268fa74ceb8fa3ab data/create/recipes/milling/bone_meal.json e84433fe6ec772c212d20109268fa74ceb8fa3ab data/create/recipes/milling/bone_meal.json
08771e9c43212ed8a378a7f4b2e5147ebe37fe0b data/create/recipes/milling/cactus.json 77b571f6ee4e8775d87077accdce4a23fb6a0c56 data/create/recipes/milling/cactus.json
d6073794b0be05fb52faf2d78d0daeb6ce3beab5 data/create/recipes/milling/calcite.json d6073794b0be05fb52faf2d78d0daeb6ce3beab5 data/create/recipes/milling/calcite.json
5b6ccdbc1bf1dcc3fc3fca94ff1fa46c17f46622 data/create/recipes/milling/charcoal.json 5b6ccdbc1bf1dcc3fc3fca94ff1fa46c17f46622 data/create/recipes/milling/charcoal.json
6323f36ea7a1a46d0999dfe24e4fa86d677e319d data/create/recipes/milling/clay.json 6323f36ea7a1a46d0999dfe24e4fa86d677e319d data/create/recipes/milling/clay.json

View file

@ -1,14 +1,5 @@
{ {
"type": "create:milling", "type": "create:milling",
"conditions": [
{
"type": "forge:not",
"value": {
"type": "forge:mod_loaded",
"modid": "quark"
}
}
],
"ingredients": [ "ingredients": [
{ {
"item": "minecraft:cactus" "item": "minecraft:cactus"

View file

@ -7,6 +7,12 @@
}, },
{ {
"item": "minecraft:dirt" "item": "minecraft:dirt"
},
{
"item": "minecraft:coarse_dirt"
},
{
"item": "minecraft:rooted_dirt"
} }
] ]
], ],

View file

@ -0,0 +1,5 @@
{
"values": [
"minecraft:sugar_cane"
]
}

View file

@ -3,6 +3,9 @@ package com.simibubi.create;
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour; import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour; import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
import static com.simibubi.create.Create.REGISTRATE; import static com.simibubi.create.Create.REGISTRATE;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour; import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock; import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
import static com.simibubi.create.foundation.data.BlockStateGen.simpleCubeAll; import static com.simibubi.create.foundation.data.BlockStateGen.simpleCubeAll;
@ -185,7 +188,7 @@ import com.simibubi.create.content.processing.basin.BasinGenerator;
import com.simibubi.create.content.processing.basin.BasinMovementBehaviour; import com.simibubi.create.content.processing.basin.BasinMovementBehaviour;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockItem; import com.simibubi.create.content.processing.burner.BlazeBurnerBlockItem;
import com.simibubi.create.content.processing.burner.BlazeBurnerInteractionBehaviour; import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
import com.simibubi.create.content.processing.burner.BlazeBurnerMovementBehaviour; import com.simibubi.create.content.processing.burner.BlazeBurnerMovementBehaviour;
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock; import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
import com.simibubi.create.content.redstone.RoseQuartzLampBlock; import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
@ -708,7 +711,7 @@ public class AllBlocks {
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable())) .loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p))) .blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour())) .onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
.onRegister(interactionBehaviour(new BlazeBurnerInteractionBehaviour())) .onRegister(block -> TrainConductorHandler.registerBlazeBurner())
.item(BlazeBurnerBlockItem::withBlaze) .item(BlazeBurnerBlockItem::withBlaze)
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze")) .model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
.build() .build()

View file

@ -7,6 +7,8 @@ import java.util.function.Supplier;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.simibubi.create.content.fluids.VirtualFluid;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.joml.Vector3f; import org.joml.Vector3f;
@ -14,7 +16,6 @@ import com.mojang.blaze3d.shaders.FogShape;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllTags.AllFluidTags; import com.simibubi.create.AllTags.AllFluidTags;
import com.simibubi.create.content.decoration.palettes.AllPaletteStoneTypes; import com.simibubi.create.content.decoration.palettes.AllPaletteStoneTypes;
import com.simibubi.create.content.fluids.VirtualFluid;
import com.simibubi.create.content.fluids.potion.PotionFluid; import com.simibubi.create.content.fluids.potion.PotionFluid;
import com.simibubi.create.content.fluids.potion.PotionFluid.PotionFluidType; import com.simibubi.create.content.fluids.potion.PotionFluid.PotionFluidType;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
@ -46,7 +47,7 @@ public class AllFluids {
} }
public static final FluidEntry<PotionFluid> POTION = public static final FluidEntry<PotionFluid> POTION =
REGISTRATE.virtualFluid("potion", PotionFluidType::new, PotionFluid::new) REGISTRATE.virtualFluid("potion", PotionFluidType::new, PotionFluid::createSource, PotionFluid::createFlowing)
.lang("Potion") .lang("Potion")
.register(); .register();

View file

@ -104,6 +104,7 @@ public class AllTags {
WINDMILL_SAILS, WINDMILL_SAILS,
WRENCH_PICKUP, WRENCH_PICKUP,
ROOTS, ROOTS,
SUGAR_CANE_VARIANTS,
CORALS, CORALS,

View file

@ -0,0 +1,54 @@
package com.simibubi.create.api.contraption.train;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllInteractionBehaviours;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* All required methods to make your block a train conductor similar to the blaze burner
*/
public interface TrainConductorHandler {
@ApiStatus.Internal
List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
boolean isValidConductor(BlockState state);
private static void registerHandler(TrainConductorHandler handler) {
CONDUCTOR_HANDLERS.add(handler);
}
static void registerConductor(ResourceLocation blockRl, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
AllInteractionBehaviours.registerBehaviour(blockRl, new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback));
registerHandler(isValidConductor::test);
}
@ApiStatus.Internal
static void registerBlazeBurner() {
registerConductor(AllBlocks.BLAZE_BURNER.getId(), blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
}
interface UpdateScheduleCallback {
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};
void update(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter);
}
}

View file

@ -36,6 +36,7 @@ public class DisplayLinkPeripheral extends SyncedPeripheral<DisplayLinkBlockEnti
@LuaFunction(mainThread = true) @LuaFunction(mainThread = true)
public final Object[] getSize() { public final Object[] getSize() {
blockEntity.updateGatheredData();
DisplayTargetStats stats = blockEntity.activeTarget.provideStats(new DisplayLinkContext(blockEntity.getLevel(), blockEntity)); DisplayTargetStats stats = blockEntity.activeTarget.provideStats(new DisplayLinkContext(blockEntity.getLevel(), blockEntity));
return new Object[]{stats.maxRows(), stats.maxColumns()}; return new Object[]{stats.maxRows(), stats.maxColumns()};
} }

View file

@ -78,6 +78,7 @@ import mezz.jei.api.forge.ForgeTypes;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.helpers.IPlatformFluidHelper; import mezz.jei.api.helpers.IPlatformFluidHelper;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IExtraIngredientRegistration;
import mezz.jei.api.registration.IGuiHandlerRegistration; import mezz.jei.api.registration.IGuiHandlerRegistration;
import mezz.jei.api.registration.IRecipeCatalystRegistration; import mezz.jei.api.registration.IRecipeCatalystRegistration;
import mezz.jei.api.registration.IRecipeCategoryRegistration; import mezz.jei.api.registration.IRecipeCategoryRegistration;
@ -90,6 +91,7 @@ import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.Recipe;
@ -98,7 +100,9 @@ import net.minecraft.world.item.crafting.SmokingRecipe;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.crafting.IShapedRecipe; import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
@JeiPlugin @JeiPlugin
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -363,6 +367,22 @@ public class CreateJEI implements IModPlugin {
registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter); registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter);
} }
@Override
public void registerExtraIngredients(IExtraIngredientRegistration registration) {
Collection<Potion> potions = ForgeRegistries.POTIONS.getValues();
Collection<FluidStack> potionFluids = new ArrayList<>(potions.size() * 3);
for (Potion potion : potions) {
// @goshante: Ingame potion fluids always have Bottle tag that specifies
// to what bottle type this potion belongs
// Potion fluid without this tag wouldn't be recognized by other mods
for (PotionFluid.BottleType bottleType : PotionFluid.BottleType.values()) {
FluidStack potionFluid = PotionFluid.of(1000, potion, bottleType);
potionFluids.add(potionFluid);
}
}
registration.addExtraIngredients(ForgeTypes.FLUID_STACK, potionFluids);
}
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@Override @Override
public void registerGuiHandlers(IGuiHandlerRegistration registration) { public void registerGuiHandlers(IGuiHandlerRegistration registration) {

View file

@ -67,7 +67,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
.addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19) .addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks())) .addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount())); .addRichTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount()));
i++; i++;
} }
@ -82,7 +82,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition) .addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(result), -1, -1) .setBackground(getRenderedSlot(result), -1, -1)
.addItemStack(result.getStack()) .addItemStack(result.getStack())
.addTooltipCallback(addStochasticTooltip(result)); .addRichTooltipCallback(addStochasticTooltip(result));
i++; i++;
} }
@ -94,7 +94,7 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition) .addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult)) .addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(fluidResult))
.addTooltipCallback(addFluidTooltip(fluidResult.getAmount())); .addRichTooltipCallback(addFluidTooltip(fluidResult.getAmount()));
i++; i++;
} }

View file

@ -8,6 +8,8 @@ import java.util.stream.Collectors;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import mezz.jei.api.gui.ingredient.IRecipeSlotRichTooltipCallback;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import com.simibubi.create.AllFluids; import com.simibubi.create.AllFluids;
@ -108,11 +110,11 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
return recipe.getResultItem(level.registryAccess()); return recipe.getResultItem(level.registryAccess());
} }
public static IRecipeSlotTooltipCallback addStochasticTooltip(ProcessingOutput output) { public static IRecipeSlotRichTooltipCallback addStochasticTooltip(ProcessingOutput output) {
return (view, tooltip) -> { return (view, tooltip) -> {
float chance = output.getChance(); float chance = output.getChance();
if (chance != 1) if (chance != 1)
tooltip.add(1, Lang.translateDirect("recipe.processing.chance", chance < 0.01 ? "<1" : (int) (chance * 100)) tooltip.add(Lang.translateDirect("recipe.processing.chance", chance < 0.01 ? "<1" : (int) (chance * 100))
.withStyle(ChatFormatting.GOLD)); .withStyle(ChatFormatting.GOLD));
}; };
} }
@ -130,11 +132,11 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
return display; return display;
} }
public static IRecipeSlotTooltipCallback addFluidTooltip() { public static IRecipeSlotRichTooltipCallback addFluidTooltip() {
return addFluidTooltip(-1); return addFluidTooltip(-1);
} }
public static IRecipeSlotTooltipCallback addFluidTooltip(int mbAmount) { public static IRecipeSlotRichTooltipCallback addFluidTooltip(int mbAmount) {
return (view, tooltip) -> { return (view, tooltip) -> {
Optional<FluidStack> displayed = view.getDisplayedIngredient(ForgeTypes.FLUID_STACK); Optional<FluidStack> displayed = view.getDisplayedIngredient(ForgeTypes.FLUID_STACK);
if (displayed.isEmpty()) if (displayed.isEmpty())
@ -143,26 +145,14 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
FluidStack fluidStack = displayed.get(); FluidStack fluidStack = displayed.get();
if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) { if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) {
Component name = fluidStack.getDisplayName();
if (tooltip.isEmpty())
tooltip.add(0, name);
else
tooltip.set(0, name);
ArrayList<Component> potionTooltip = new ArrayList<>(); ArrayList<Component> potionTooltip = new ArrayList<>();
PotionFluidHandler.addPotionTooltip(fluidStack, potionTooltip, 1); PotionFluidHandler.addPotionTooltip(fluidStack, potionTooltip, 1);
tooltip.addAll(1, potionTooltip.stream().toList()); tooltip.addAll(potionTooltip.stream().toList());
} }
int amount = mbAmount == -1 ? fluidStack.getAmount() : mbAmount; int amount = mbAmount == -1 ? fluidStack.getAmount() : mbAmount;
Component text = Components.literal(String.valueOf(amount)).append(Lang.translateDirect("generic.unit.millibuckets")).withStyle(ChatFormatting.GOLD); Component text = Components.literal(String.valueOf(amount)).append(Lang.translateDirect("generic.unit.millibuckets")).withStyle(ChatFormatting.GOLD);
if (tooltip.isEmpty()) tooltip.add(text);
tooltip.add(0, text);
else {
List<Component> siblings = tooltip.get(0).getSiblings();
siblings.add(Components.literal(" "));
siblings.add(text);
}
}; };
} }

View file

@ -41,7 +41,7 @@ public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecip
.addSlot(RecipeIngredientRole.OUTPUT, (xOffset) + layoutEntry.posX() + 1, yOffset + layoutEntry.posY() + 1) .addSlot(RecipeIngredientRole.OUTPUT, (xOffset) + layoutEntry.posX() + 1, yOffset + layoutEntry.posY() + 1)
.setBackground(getRenderedSlot(layoutEntry.output()), -1, -1) .setBackground(getRenderedSlot(layoutEntry.output()), -1, -1)
.addItemStack(layoutEntry.output().getStack()) .addItemStack(layoutEntry.output().getStack())
.addTooltipCallback(addStochasticTooltip(layoutEntry.output())) .addRichTooltipCallback(addStochasticTooltip(layoutEntry.output()))
); );
} }

View file

@ -47,7 +47,7 @@ public class DeployingCategory extends CreateRecipeCategory<DeployerApplicationR
builder.addSlot(RecipeIngredientRole.OUTPUT, single ? 132 : 132 + xOffset, 51 + yOffset) builder.addSlot(RecipeIngredientRole.OUTPUT, single ? 132 : 132 + xOffset, 51 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
} }
if (recipe.shouldKeepHeldItem()) if (recipe.shouldKeepHeldItem())

View file

@ -58,7 +58,7 @@ public class ItemApplicationCategory extends CreateRecipeCategory<ItemApplicatio
builder.addSlot(RecipeIngredientRole.OUTPUT, single ? 132 : 132 + xOffset, 38 + yOffset) builder.addSlot(RecipeIngredientRole.OUTPUT, single ? 132 : 132 + xOffset, 38 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
} }
} }

View file

@ -100,7 +100,7 @@ public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
.addSlot(RecipeIngredientRole.OUTPUT, 132, 8) .addSlot(RecipeIngredientRole.OUTPUT, 132, 8)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getResultingFluid())) .addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getResultingFluid()))
.addTooltipCallback(addFluidTooltip(recipe.getResultingFluid().getAmount())); .addRichTooltipCallback(addFluidTooltip(recipe.getResultingFluid().getAmount()));
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 27) .addSlot(RecipeIngredientRole.OUTPUT, 132, 27)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)

View file

@ -42,7 +42,7 @@ public class MillingCategory extends CreateRecipeCategory<AbstractCrushingRecipe
.addSlot(RecipeIngredientRole.OUTPUT, single ? 139 : 133 + xOffset, 27 + yOffset) .addSlot(RecipeIngredientRole.OUTPUT, single ? 139 : 133 + xOffset, 27 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
i++; i++;
} }

View file

@ -40,7 +40,7 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
.addSlot(RecipeIngredientRole.OUTPUT, 132, 29) .addSlot(RecipeIngredientRole.OUTPUT, 132, 29)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
} }
@Override @Override

View file

@ -37,7 +37,7 @@ public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
builder.addSlot(RecipeIngredientRole.OUTPUT, 131 + 19 * i, 50) builder.addSlot(RecipeIngredientRole.OUTPUT, 131 + 19 * i, 50)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
i++; i++;
} }
} }

View file

@ -117,7 +117,7 @@ public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends Crea
.addSlot(RecipeIngredientRole.OUTPUT, 141 + xOffset, 48 + yOffset) .addSlot(RecipeIngredientRole.OUTPUT, 141 + xOffset, 48 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
i++; i++;
} }
} }

View file

@ -40,7 +40,7 @@ public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
.addSlot(RecipeIngredientRole.OUTPUT, 118 + xOffset, 48 + yOffset) .addSlot(RecipeIngredientRole.OUTPUT, 118 + xOffset, 48 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1) .setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack()) .addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output)); .addRichTooltipCallback(addStochasticTooltip(output));
i++; i++;
} }
} }

View file

@ -112,7 +112,7 @@ public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
.addSlot(RecipeIngredientRole.INPUT, 27, 32) .addSlot(RecipeIngredientRole.INPUT, 27, 32)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getRequiredFluid().getMatchingFluidStacks())) .addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getRequiredFluid().getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(recipe.getRequiredFluid().getRequiredAmount())); .addRichTooltipCallback(addFluidTooltip(recipe.getRequiredFluid().getRequiredAmount()));
builder builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 51) .addSlot(RecipeIngredientRole.OUTPUT, 132, 51)
.setBackground(getRenderedSlot(), -1, -1) .setBackground(getRenderedSlot(), -1, -1)

View file

@ -76,7 +76,7 @@ public abstract class SequencedAssemblySubCategory {
.addSlot(RecipeIngredientRole.INPUT, x + 4, 15) .addSlot(RecipeIngredientRole.INPUT, x + 4, 15)
.setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1) .setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1)
.addIngredients(ForgeTypes.FLUID_STACK, CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks())) .addIngredients(ForgeTypes.FLUID_STACK, CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(CreateRecipeCategory.addFluidTooltip(fluidIngredient.getRequiredAmount())); .addRichTooltipCallback(CreateRecipeCategory.addFluidTooltip(fluidIngredient.getRequiredAmount()));
} }
@Override @Override

View file

@ -4,6 +4,7 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
@ -173,7 +174,7 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
if (block == Blocks.SWEET_BERRY_BUSH) { if (block == Blocks.SWEET_BERRY_BUSH) {
return state.setValue(BlockStateProperties.AGE_3, Integer.valueOf(1)); return state.setValue(BlockStateProperties.AGE_3, Integer.valueOf(1));
} }
if (block == Blocks.SUGAR_CANE || block instanceof GrowingPlantBlock) { if (state.is(AllTags.AllBlockTags.SUGAR_CANE_VARIANTS.tag) || block instanceof GrowingPlantBlock) {
if (state.getFluidState() if (state.getFluidState()
.isEmpty()) .isEmpty())
return Blocks.AIR.defaultBlockState(); return Blocks.AIR.defaultBlockState();

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.fluids; package com.simibubi.create.content.fluids;
import com.simibubi.create.content.fluids.potion.PotionFluid;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -10,17 +12,35 @@ import net.minecraftforge.fluids.ForgeFlowingFluid;
public class VirtualFluid extends ForgeFlowingFluid { public class VirtualFluid extends ForgeFlowingFluid {
public VirtualFluid(Properties properties) { public static VirtualFluid createSource(Properties properties) {
return new VirtualFluid(properties, true);
}
public static VirtualFluid createFlowing(Properties properties) {
return new VirtualFluid(properties, false);
}
private final boolean source;
public VirtualFluid(Properties properties, boolean source) {
super(properties); super(properties);
this.source = source;
} }
@Override @Override
public Fluid getSource() { public Fluid getSource() {
if (source) {
return this;
}
return super.getSource(); return super.getSource();
} }
@Override @Override
public Fluid getFlowing() { public Fluid getFlowing() {
if (source) {
return super.getFlowing();
}
return this; return this;
} }
@ -36,7 +56,7 @@ public class VirtualFluid extends ForgeFlowingFluid {
@Override @Override
public boolean isSource(FluidState p_207193_1_) { public boolean isSource(FluidState p_207193_1_) {
return false; return source;
} }
@Override @Override

View file

@ -24,19 +24,29 @@ import net.minecraftforge.fluids.FluidStack;
public class PotionFluid extends VirtualFluid { public class PotionFluid extends VirtualFluid {
public PotionFluid(Properties properties) { public static PotionFluid createSource(Properties properties) {
super(properties); return new PotionFluid(properties, true);
} }
public static FluidStack of(int amount, Potion potion) { public static PotionFluid createFlowing(Properties properties) {
FluidStack fluidStack = new FluidStack(AllFluids.POTION.get() return new PotionFluid(properties, false);
.getSource(), amount); }
public PotionFluid(Properties properties, boolean source) {
super(properties, source);
}
public static FluidStack of(int amount, Potion potion, BottleType bottleType) {
FluidStack fluidStack;
fluidStack = new FluidStack(AllFluids.POTION.get().getSource(), amount);
addPotionToFluidStack(fluidStack, potion); addPotionToFluidStack(fluidStack, potion);
NBTHelper.writeEnum(fluidStack.getOrCreateTag(), "Bottle", bottleType);
return fluidStack; return fluidStack;
} }
public static FluidStack withEffects(int amount, Potion potion, List<MobEffectInstance> customEffects) { public static FluidStack withEffects(int amount, Potion potion, List<MobEffectInstance> customEffects) {
FluidStack fluidStack = of(amount, potion); FluidStack fluidStack = of(amount, potion, BottleType.REGULAR);
appendEffects(fluidStack, customEffects); appendEffects(fluidStack, customEffects);
return fluidStack; return fluidStack;
} }

View file

@ -69,8 +69,7 @@ public class PotionFluidHandler {
public static FluidStack getFluidFromPotion(Potion potion, BottleType bottleType, int amount) { public static FluidStack getFluidFromPotion(Potion potion, BottleType bottleType, int amount) {
if (potion == Potions.WATER && bottleType == BottleType.REGULAR) if (potion == Potions.WATER && bottleType == BottleType.REGULAR)
return new FluidStack(Fluids.WATER, amount); return new FluidStack(Fluids.WATER, amount);
FluidStack fluid = PotionFluid.of(amount, potion); FluidStack fluid = PotionFluid.of(amount, potion, bottleType);
NBTHelper.writeEnum(fluid.getOrCreateTag(), "Bottle", bottleType);
return fluid; return fluid;
} }

View file

@ -232,6 +232,8 @@ public class SpoutBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
protected void spawnProcessingParticles(FluidStack fluid) { protected void spawnProcessingParticles(FluidStack fluid) {
if (isVirtual()) if (isVirtual())
return; return;
if (fluid.isEmpty())
return;
Vec3 vec = VecHelper.getCenterOf(worldPosition); Vec3 vec = VecHelper.getCenterOf(worldPosition);
vec = vec.subtract(0, 8 / 16f, 0); vec = vec.subtract(0, 8 / 16f, 0);
ParticleOptions particle = FluidFX.getFluidParticle(fluid); ParticleOptions particle = FluidFX.getFluidParticle(fluid);

View file

@ -65,9 +65,9 @@ public class SpoutRenderer extends SafeBlockEntityRenderer<SpoutBlockEntity> {
processingProgress = Mth.clamp(processingProgress, 0, 1); processingProgress = Mth.clamp(processingProgress, 0, 1);
float radius = 0; float radius = 0;
if (processingTicks != -1) { if (!fluidStack.isEmpty() && processingTicks != -1) {
radius = (float) (Math.pow(((2 * processingProgress) - 1), 2) - 1); radius = (float) (Math.pow(((2 * processingProgress) - 1), 2) - 1);
AABB bb = new AABB(0.5, .5, 0.5, 0.5, -1.2, 0.5).inflate(radius / 32f); AABB bb = new AABB(0.5, 0.0, 0.5, 0.5, -1.2, 0.5).inflate(radius / 32f);
FluidRenderer.renderFluidBox(fluidStack, (float) bb.minX, (float) bb.minY, (float) bb.minZ, FluidRenderer.renderFluidBox(fluidStack, (float) bb.minX, (float) bb.minY, (float) bb.minZ,
(float) bb.maxX, (float) bb.maxY, (float) bb.maxZ, buffer, ms, light, true); (float) bb.maxX, (float) bb.maxY, (float) bb.maxZ, buffer, ms, light, true);
} }

View file

@ -184,8 +184,9 @@ public class DeployerHandler {
if (stack.isEdible()) { if (stack.isEdible()) {
FoodProperties foodProperties = item.getFoodProperties(stack, player); FoodProperties foodProperties = item.getFoodProperties(stack, player);
if (playerEntity.canEat(foodProperties.canAlwaysEat())) { if (playerEntity.canEat(foodProperties.canAlwaysEat())) {
playerEntity.eat(world, stack); ItemStack copy = stack.copy();
player.spawnedItemEffects = stack.copy(); player.setItemInHand(hand, stack.finishUsingItem(world, playerEntity));
player.spawnedItemEffects = copy;
success = true; success = true;
} }
} }

View file

@ -2,10 +2,10 @@ package com.simibubi.create.content.processing.burner;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.CarriageContraption;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.entity.Train;
@ -21,9 +21,21 @@ import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour { import java.util.function.Predicate;
public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteractionBehaviour {
private final Predicate<BlockState> isValidConductor;
private final TrainConductorHandler.UpdateScheduleCallback callback;
public BlockBasedTrainConductorInteractionBehaviour(Predicate<BlockState> isValidConductor, TrainConductorHandler.UpdateScheduleCallback callback) {
this.isValidConductor = isValidConductor;
this.callback = callback;
}
@Override @Override
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos, public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
@ -40,8 +52,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
StructureBlockInfo info = carriageContraption.getBlocks() StructureBlockInfo info = carriageContraption.getBlocks()
.get(localPos); .get(localPos);
if (info == null || !info.state().hasProperty(BlazeBurnerBlock.HEAT_LEVEL) if (info == null || !isValidConductor.test(info.state()))
|| info.state().getValue(BlazeBurnerBlock.HEAT_LEVEL) == HeatLevel.NONE)
return false; return false;
Direction assemblyDirection = carriageContraption.getAssemblyDirection(); Direction assemblyDirection = carriageContraption.getAssemblyDirection();
@ -74,6 +85,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"), train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"),
true); true);
player.setItemInHand(activeHand, train.runtime.returnSchedule()); player.setItemInHand(activeHand, train.runtime.returnSchedule());
callback.update(false, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
return true; return true;
} }
@ -89,7 +101,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
player.displayClientMessage(Lang.translateDirect("schedule.no_stops"), true); player.displayClientMessage(Lang.translateDirect("schedule.no_stops"), true);
return true; return true;
} }
callback.update(true, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
train.runtime.setSchedule(schedule, false); train.runtime.setSchedule(schedule, false);
AllAdvancements.CONDUCTOR.awardTo(player); AllAdvancements.CONDUCTOR.awardTo(player);
AllSoundEvents.CONFIRM.playOnServer(player.level(), player.blockPosition(), 1, 1); AllSoundEvents.CONFIRM.playOnServer(player.level(), player.blockPosition(), 1, 1);
@ -105,4 +117,10 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
return true; return true;
} }
private void setBlockState(BlockPos localPos, AbstractContraptionEntity contraption, BlockState newState) {
StructureTemplate.StructureBlockInfo info = contraption.getContraption().getBlocks().get(localPos);
if (info != null) {
setContraptionBlockData(contraption, localPos, new StructureTemplate.StructureBlockInfo(info.pos(), newState, info.nbt()));
}
}
} }

View file

@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
@ -17,8 +19,6 @@ import com.simibubi.create.content.contraptions.ContraptionType;
import com.simibubi.create.content.contraptions.MountedStorageManager; import com.simibubi.create.content.contraptions.MountedStorageManager;
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock; import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock;
import com.simibubi.create.content.contraptions.minecart.TrainCargoManager; import com.simibubi.create.content.contraptions.minecart.TrainCargoManager;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock; import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -51,7 +51,7 @@ public class CarriageContraption extends Contraption {
private boolean forwardControls; private boolean forwardControls;
private boolean backwardControls; private boolean backwardControls;
public Couple<Boolean> blazeBurnerConductors; public Couple<Boolean> blockConductors;
public Map<BlockPos, Couple<Boolean>> conductorSeats; public Map<BlockPos, Couple<Boolean>> conductorSeats;
public ArrivalSoundQueue soundQueue; public ArrivalSoundQueue soundQueue;
@ -61,7 +61,7 @@ public class CarriageContraption extends Contraption {
private int bogeys; private int bogeys;
private boolean sidewaysControls; private boolean sidewaysControls;
private BlockPos secondBogeyPos; private BlockPos secondBogeyPos;
private List<BlockPos> assembledBlazeBurners; private List<BlockPos> assembledBlockConductors;
// render // render
public int portalCutoffMin; public int portalCutoffMin;
@ -72,8 +72,8 @@ public class CarriageContraption extends Contraption {
public CarriageContraption() { public CarriageContraption() {
conductorSeats = new HashMap<>(); conductorSeats = new HashMap<>();
assembledBlazeBurners = new ArrayList<>(); assembledBlockConductors = new ArrayList<>();
blazeBurnerConductors = Couple.create(false, false); blockConductors = Couple.create(false, false);
soundQueue = new ArrivalSoundQueue(); soundQueue = new ArrivalSoundQueue();
portalCutoffMin = Integer.MIN_VALUE; portalCutoffMin = Integer.MIN_VALUE;
portalCutoffMax = Integer.MAX_VALUE; portalCutoffMax = Integer.MAX_VALUE;
@ -103,10 +103,10 @@ public class CarriageContraption extends Contraption {
if (sidewaysControls) if (sidewaysControls)
throw new AssemblyException(Lang.translateDirect("train_assembly.sideways_controls")); throw new AssemblyException(Lang.translateDirect("train_assembly.sideways_controls"));
for (BlockPos blazePos : assembledBlazeBurners) for (BlockPos blazePos : assembledBlockConductors)
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis())) for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
if (inControl(blazePos, direction)) if (inControl(blazePos, direction))
blazeBurnerConductors.set(direction != assemblyDirection, true); blockConductors.set(direction != assemblyDirection, true);
for (BlockPos seatPos : getSeats()) for (BlockPos seatPos : getSeats())
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis())) for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
if (inControl(seatPos, direction)) if (inControl(seatPos, direction))
@ -166,9 +166,8 @@ public class CarriageContraption extends Contraption {
captureBE ? world.getBlockEntity(pos) : null); captureBE ? world.getBlockEntity(pos) : null);
} }
if (AllBlocks.BLAZE_BURNER.has(blockState) if (TrainConductorHandler.CONDUCTOR_HANDLERS.stream().anyMatch(handler -> handler.isValidConductor(blockState)))
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != HeatLevel.NONE) assembledBlockConductors.add(toLocalPos(pos));
assembledBlazeBurners.add(toLocalPos(pos));
if (AllBlocks.TRAIN_CONTROLS.has(blockState)) { if (AllBlocks.TRAIN_CONTROLS.has(blockState)) {
Direction facing = blockState.getValue(ControlsBlock.FACING); Direction facing = blockState.getValue(ControlsBlock.FACING);
@ -192,8 +191,8 @@ public class CarriageContraption extends Contraption {
NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection()); NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection());
tag.putBoolean("FrontControls", forwardControls); tag.putBoolean("FrontControls", forwardControls);
tag.putBoolean("BackControls", backwardControls); tag.putBoolean("BackControls", backwardControls);
tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst()); tag.putBoolean("FrontBlazeConductor", blockConductors.getFirst());
tag.putBoolean("BackBlazeConductor", blazeBurnerConductors.getSecond()); tag.putBoolean("BackBlazeConductor", blockConductors.getSecond());
ListTag list = NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> { ListTag list = NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> {
CompoundTag compoundTag = new CompoundTag(); CompoundTag compoundTag = new CompoundTag();
compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey())); compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey()));
@ -213,7 +212,7 @@ public class CarriageContraption extends Contraption {
assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class); assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class);
forwardControls = nbt.getBoolean("FrontControls"); forwardControls = nbt.getBoolean("FrontControls");
backwardControls = nbt.getBoolean("BackControls"); backwardControls = nbt.getBoolean("BackControls");
blazeBurnerConductors = blockConductors =
Couple.create(nbt.getBoolean("FrontBlazeConductor"), nbt.getBoolean("BackBlazeConductor")); Couple.create(nbt.getBoolean("FrontBlazeConductor"), nbt.getBoolean("BackBlazeConductor"));
conductorSeats.clear(); conductorSeats.clear();
NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND), NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND),

View file

@ -492,8 +492,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
if (!(contraption instanceof CarriageContraption cc)) if (!(contraption instanceof CarriageContraption cc))
return sides; return sides;
sides.setFirst(cc.blazeBurnerConductors.getFirst()); sides.setFirst(cc.blockConductors.getFirst());
sides.setSecond(cc.blazeBurnerConductors.getSecond()); sides.setSecond(cc.blockConductors.getSecond());
for (Entity entity : getPassengers()) { for (Entity entity : getPassengers()) {
if (entity instanceof Player) if (entity instanceof Player)

View file

@ -172,29 +172,30 @@ public class CreateRegistrate extends AbstractRegistrate<CreateRegistrate> {
/* Fluids */ /* Fluids */
public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name, public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name,
FluidBuilder.FluidTypeFactory typeFactory, NonNullFunction<ForgeFlowingFluid.Properties, T> factory) { FluidBuilder.FluidTypeFactory typeFactory, NonNullFunction<ForgeFlowingFluid.Properties, T> sourceFactory,
NonNullFunction<ForgeFlowingFluid.Properties, T> flowingFactory) {
return entry(name, return entry(name,
c -> new VirtualFluidBuilder<>(self(), self(), name, c, new ResourceLocation(getModid(), "fluid/" + name + "_still"), c -> new VirtualFluidBuilder<>(self(), self(), name, c, new ResourceLocation(getModid(), "fluid/" + name + "_still"),
new ResourceLocation(getModid(), "fluid/" + name + "_flow"), typeFactory, factory)); new ResourceLocation(getModid(), "fluid/" + name + "_flow"), typeFactory, sourceFactory, flowingFactory));
} }
public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name, public <T extends ForgeFlowingFluid> FluidBuilder<T, CreateRegistrate> virtualFluid(String name,
ResourceLocation still, ResourceLocation flow, FluidBuilder.FluidTypeFactory typeFactory, ResourceLocation still, ResourceLocation flow, FluidBuilder.FluidTypeFactory typeFactory,
NonNullFunction<ForgeFlowingFluid.Properties, T> factory) { NonNullFunction<ForgeFlowingFluid.Properties, T> sourceFactory, NonNullFunction<ForgeFlowingFluid.Properties, T> flowingFactory) {
return entry(name, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow, typeFactory, factory)); return entry(name, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow, typeFactory, sourceFactory, flowingFactory));
} }
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name) { public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name) {
return entry(name, return entry(name,
c -> new VirtualFluidBuilder<VirtualFluid, CreateRegistrate>(self(), self(), name, c, c -> new VirtualFluidBuilder<VirtualFluid, CreateRegistrate>(self(), self(), name, c,
new ResourceLocation(getModid(), "fluid/" + name + "_still"), new ResourceLocation(getModid(), "fluid/" + name + "_flow"), new ResourceLocation(getModid(), "fluid/" + name + "_still"), new ResourceLocation(getModid(), "fluid/" + name + "_flow"),
CreateRegistrate::defaultFluidType, VirtualFluid::new)); CreateRegistrate::defaultFluidType, VirtualFluid::createSource, VirtualFluid::createFlowing));
} }
public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name, ResourceLocation still, public FluidBuilder<VirtualFluid, CreateRegistrate> virtualFluid(String name, ResourceLocation still,
ResourceLocation flow) { ResourceLocation flow) {
return entry(name, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow, return entry(name, c -> new VirtualFluidBuilder<>(self(), self(), name, c, still, flow,
CreateRegistrate::defaultFluidType, VirtualFluid::new)); CreateRegistrate::defaultFluidType, VirtualFluid::createSource, VirtualFluid::createFlowing));
} }
public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name) { public FluidBuilder<ForgeFlowingFluid.Flowing, CreateRegistrate> standardFluid(String name) {

View file

@ -17,9 +17,11 @@ public class VirtualFluidBuilder<T extends ForgeFlowingFluid, P> extends FluidBu
public VirtualFluidBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, public VirtualFluidBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback,
ResourceLocation stillTexture, ResourceLocation flowingTexture, FluidBuilder.FluidTypeFactory typeFactory, ResourceLocation stillTexture, ResourceLocation flowingTexture, FluidBuilder.FluidTypeFactory typeFactory,
NonNullFunction<Properties, T> factory) { NonNullFunction<Properties, T> sourceFactory,
super(owner, parent, name, callback, stillTexture, flowingTexture, typeFactory, factory); NonNullFunction<Properties, T> flowingFactory
source(factory); ) {
super(owner, parent, name, callback, stillTexture, flowingTexture, typeFactory, flowingFactory);
source(sourceFactory);
} }
@Override @Override

View file

@ -62,8 +62,7 @@ public class MillingRecipeGen extends ProcessingRecipeGen {
CACTUS = create(() -> Blocks.CACTUS, b -> b.duration(50) CACTUS = create(() -> Blocks.CACTUS, b -> b.duration(50)
.output(Items.GREEN_DYE, 2) .output(Items.GREEN_DYE, 2)
.output(.1f, Items.GREEN_DYE, 1) .output(.1f, Items.GREEN_DYE, 1)),
.whenModMissing("quark")),
SEA_PICKLE = create(() -> Blocks.SEA_PICKLE, b -> b.duration(50) SEA_PICKLE = create(() -> Blocks.SEA_PICKLE, b -> b.duration(50)
.output(Items.LIME_DYE, 2) .output(Items.LIME_DYE, 2)

View file

@ -14,7 +14,7 @@ public class PressingRecipeGen extends ProcessingRecipeGen {
SUGAR_CANE = create(() -> Items.SUGAR_CANE, b -> b.output(Items.PAPER)), SUGAR_CANE = create(() -> Items.SUGAR_CANE, b -> b.output(Items.PAPER)),
PATH = create("path", b -> b.require(Ingredient.of(Items.GRASS_BLOCK, Items.DIRT)) PATH = create("path", b -> b.require(Ingredient.of(Items.GRASS_BLOCK, Items.DIRT, Items.COARSE_DIRT, Items.ROOTED_DIRT))
.output(Items.DIRT_PATH)), .output(Items.DIRT_PATH)),
IRON = create("iron_ingot", b -> b.require(I.iron()) IRON = create("iron_ingot", b -> b.require(I.iron())

View file

@ -111,6 +111,9 @@ public class CreateRegistrateTags {
prov.tag(AllBlockTags.ROOTS.tag) prov.tag(AllBlockTags.ROOTS.tag)
.add(Blocks.MANGROVE_ROOTS); .add(Blocks.MANGROVE_ROOTS);
prov.tag(AllBlockTags.SUGAR_CANE_VARIANTS.tag)
.add(Blocks.SUGAR_CANE);
prov.tag(AllBlockTags.CORALS.tag) prov.tag(AllBlockTags.CORALS.tag)
.add(Blocks.DEAD_TUBE_CORAL, Blocks.DEAD_BRAIN_CORAL, Blocks.DEAD_BUBBLE_CORAL, Blocks.DEAD_FIRE_CORAL, .add(Blocks.DEAD_TUBE_CORAL, Blocks.DEAD_BRAIN_CORAL, Blocks.DEAD_BUBBLE_CORAL, Blocks.DEAD_FIRE_CORAL,
Blocks.DEAD_HORN_CORAL, Blocks.TUBE_CORAL, Blocks.BRAIN_CORAL, Blocks.BUBBLE_CORAL, Blocks.DEAD_HORN_CORAL, Blocks.TUBE_CORAL, Blocks.BRAIN_CORAL, Blocks.BUBBLE_CORAL,

View file

@ -36,3 +36,10 @@ Technology that empowers the player.'''
versionRange="[1.0.0-alpha,2.0)" versionRange="[1.0.0-alpha,2.0)"
ordering="AFTER" ordering="AFTER"
side="CLIENT" side="CLIENT"
[[dependencies.create]]
modId="jei"
mandatory=false
versionRange="[15.19.0,)"
ordering="NONE"
side="CLIENT"