Back on Patch, Part II

- Fixed piston/pulleys moving before their attached entity is loaded
- Recipes with an id suffixed "_manual_only" are now ignored in auto-shaped, auto-shapeless and auto-cutting processing features
- Fixed pipes spawning particles at connections between chunks
- Fixed pipes not initialising target fluid holders properly when the source is loaded in first
- Fixed encased fluid pipes not updating flows when neighbouring blocks change
- Fixed fluid pipes not updating flows when adjacent block changes from fluid to block
This commit is contained in:
simibubi 2021-11-22 00:55:08 +01:00
parent f3109b28ab
commit 88e487cdf5
14 changed files with 59 additions and 24 deletions

View file

@ -1747,7 +1747,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
58880e397902f8ca5b3b59ed4423e626109ddc4c assets/create/sounds.json 58880e397902f8ca5b3b59ed4423e626109ddc4c assets/create/sounds.json
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json
187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json 187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json
0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json 0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json 83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json

View file

@ -28,8 +28,8 @@
"trigger": "create:bracket_apply", "trigger": "create:bracket_apply",
"conditions": { "conditions": {
"accepted_entries": [ "accepted_entries": [
"create:cogwheel", "create:large_cogwheel",
"create:large_cogwheel" "create:cogwheel"
] ]
} }
}, },

View file

@ -132,4 +132,10 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
}); });
} }
public static boolean isManualRecipe(IRecipe<?> recipe) {
return recipe.getId()
.getPath()
.endsWith("_manual_only");
}
} }

View file

@ -127,7 +127,8 @@ public class CreateJEI implements IModPlugin {
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless) autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.recipes(r -> r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE && r.getIngredients() .recipes(r -> r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE && r.getIngredients()
.size() > 1 && !MechanicalPressTileEntity.canCompress(r), BasinRecipe::convertShapeless) .size() > 1 && !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.isManualRecipe(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer) .enableWhen(c -> c.allowShapelessInMixer)
@ -144,14 +145,16 @@ public class CreateJEI implements IModPlugin {
.build(), .build(),
blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS)) blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
.recipeList(() -> CondensedBlockCuttingRecipe.condenseRecipes(findRecipesByType(IRecipeType.STONECUTTING))) .recipeList(() -> CondensedBlockCuttingRecipe.condenseRecipes(findRecipes(
recipe -> recipe.getType() == IRecipeType.STONECUTTING && !AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get) .catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhen(c -> c.allowStonecuttingOnSaw) .enableWhen(c -> c.allowStonecuttingOnSaw)
.build(), .build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS)) woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.recipeList(() -> CondensedBlockCuttingRecipe .recipeList(() -> CondensedBlockCuttingRecipe
.condenseRecipes(findRecipesByType(SawTileEntity.woodcuttingRecipeType.get()))) .condenseRecipes(findRecipes(recipe -> recipe.getType() == SawTileEntity.woodcuttingRecipeType.get()
&& !AllRecipeTypes.isManualRecipe(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get) .catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get() .enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft")) .isLoaded("druidcraft"))
@ -163,8 +166,8 @@ public class CreateJEI implements IModPlugin {
.build(), .build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare) autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.recipes(r -> (r instanceof ICraftingRecipe) && MechanicalPressTileEntity.canCompress(r), .recipes(r -> (r instanceof ICraftingRecipe) && MechanicalPressTileEntity.canCompress(r)
BasinRecipe::convertShapeless) && !AllRecipeTypes.isManualRecipe(r), BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get) .catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress) .enableWhen(c -> c.allowShapedSquareInPress)
@ -203,7 +206,8 @@ public class CreateJEI implements IModPlugin {
.recipes(r -> r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE && r.getIngredients() .recipes(r -> r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE && r.getIngredients()
.size() == 1) .size() == 1)
.recipes(r -> (r.getType() == IRecipeType.CRAFTING .recipes(r -> (r.getType() == IRecipeType.CRAFTING
&& r.getType() != AllRecipeTypes.MECHANICAL_CRAFTING.getType()) && (r instanceof ShapedRecipe)) && r.getType() != AllRecipeTypes.MECHANICAL_CRAFTING.getType()) && (r instanceof ShapedRecipe)
&& !AllRecipeTypes.isManualRecipe(r))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter) .enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(), .build(),

View file

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

View file

@ -231,7 +231,8 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
return ((r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE return ((r.getSerializer() == IRecipeSerializer.SHAPELESS_RECIPE
&& AllConfigs.SERVER.recipes.allowShapelessInMixer.get() && r.getIngredients() && AllConfigs.SERVER.recipes.allowShapelessInMixer.get() && r.getIngredients()
.size() > 1 .size() > 1
&& !MechanicalPressTileEntity.canCompress(r)) || r.getType() == AllRecipeTypes.MIXING.getType()); && !MechanicalPressTileEntity.canCompress(r)) && !AllRecipeTypes.isManualRecipe(r)
|| r.getType() == AllRecipeTypes.MIXING.getType());
} }
@Override @Override

View file

@ -362,7 +362,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
@Override @Override
protected <C extends IInventory> boolean matchStaticFilters(IRecipe<C> recipe) { protected <C extends IInventory> boolean matchStaticFilters(IRecipe<C> recipe) {
return (recipe instanceof ICraftingRecipe && canCompress(recipe)) return (recipe instanceof ICraftingRecipe && canCompress(recipe) && !AllRecipeTypes.isManualRecipe(recipe))
|| recipe.getType() == AllRecipeTypes.COMPACTING.getType(); || recipe.getType() == AllRecipeTypes.COMPACTING.getType();
} }

View file

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

View file

@ -28,6 +28,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
public float offset; public float offset;
public boolean running; public boolean running;
public boolean assembleNextTick; public boolean assembleNextTick;
public boolean needsContraption;
public AbstractContraptionEntity movedContraption; public AbstractContraptionEntity movedContraption;
protected boolean forceMove; protected boolean forceMove;
protected ScrollOptionBehaviour<MovementMode> movementMode; protected ScrollOptionBehaviour<MovementMode> movementMode;
@ -41,6 +42,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
super(typeIn); super(typeIn);
setLazyTickRate(3); setLazyTickRate(3);
forceMove = true; forceMove = true;
needsContraption = true;
} }
@Override @Override
@ -65,7 +67,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
if (level.isClientSide) if (level.isClientSide)
clientOffsetDiff *= .75f; clientOffsetDiff *= .75f;
if (waitingForSpeedChange && movedContraption != null) { if (waitingForSpeedChange) {
if (movedContraption != null) {
if (level.isClientSide) { if (level.isClientSide) {
float syncSpeed = clientOffsetDiff / 2f; float syncSpeed = clientOffsetDiff / 2f;
offset += syncSpeed; offset += syncSpeed;
@ -73,6 +76,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
return; return;
} }
movedContraption.setContraptionMotion(Vector3d.ZERO); movedContraption.setContraptionMotion(Vector3d.ZERO);
}
return; return;
} }
@ -101,6 +105,9 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
return; return;
boolean contraptionPresent = movedContraption != null; boolean contraptionPresent = movedContraption != null;
if (needsContraption && !contraptionPresent)
return;
float movementSpeed = getMovementSpeed(); float movementSpeed = getMovementSpeed();
float newOffset = offset + movementSpeed; float newOffset = offset + movementSpeed;
if ((int) newOffset != (int) offset) if ((int) newOffset != (int) offset)

View file

@ -75,6 +75,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
// Collect Construct // Collect Construct
if (!level.isClientSide) { if (!level.isClientSide) {
needsContraption = false;
BlockPos anchor = worldPosition.below(MathHelper.floor(offset + 1)); BlockPos anchor = worldPosition.below(MathHelper.floor(offset + 1));
initialOffset = MathHelper.floor(offset); initialOffset = MathHelper.floor(offset);
PulleyContraption contraption = new PulleyContraption(initialOffset); PulleyContraption contraption = new PulleyContraption(initialOffset);
@ -107,6 +108,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
movedContraption.setPos(anchor.getX(), anchor.getY(), anchor.getZ()); movedContraption.setPos(anchor.getX(), anchor.getY(), anchor.getZ());
level.addFreshEntity(movedContraption); level.addFreshEntity(movedContraption);
forceMove = true; forceMove = true;
needsContraption = true;
} }
} }
@ -198,6 +200,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
@Override @Override
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
initialOffset = compound.getInt("InitialOffset"); initialOffset = compound.getInt("InitialOffset");
needsContraption = compound.getBoolean("NeedsContraption");
super.fromTag(state, compound, clientPacket); super.fromTag(state, compound, clientPacket);
} }

View file

@ -133,6 +133,12 @@ public class FluidNetwork {
continue; continue;
} }
// Give pipe end a chance to init connections
if (!adjacent.source.isPresent() && !adjacent.determineSource(world, blockFace.getPos())) {
canRemove = false;
continue;
}
if (adjacent.source.isPresent() && adjacent.source.get() if (adjacent.source.isPresent() && adjacent.source.get()
.isEndpoint()) { .isEndpoint()) {
targets.add(Pair.of(adjacentLocation, adjacent.source.get() targets.add(Pair.of(adjacentLocation, adjacent.source.get()

View file

@ -133,7 +133,7 @@ public class FluidPropagator {
return null; return null;
if (otherBlock instanceof FlowingFluidBlock) if (otherBlock instanceof FlowingFluidBlock)
return null; return null;
if (getStraightPipeAxis(state) == null) if (getStraightPipeAxis(state) == null && !AllBlocks.ENCASED_FLUID_PIPE.has(state))
return null; return null;
for (Direction d : Iterate.directions) { for (Direction d : Iterate.directions) {
if (!pos.relative(d) if (!pos.relative(d)

View file

@ -24,6 +24,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
@ -159,11 +160,13 @@ public class PipeConnection {
return true; return true;
} }
private boolean determineSource(World world, BlockPos pos) { public boolean determineSource(World world, BlockPos pos) {
if (!world.isAreaLoaded(pos, 1)) BlockPos relative = pos.relative(side);
// cannot use world.isLoaded because it always returns true onclient
if (world.getChunk(relative.getX() >> 4, relative.getZ() >> 4, ChunkStatus.FULL, false) == null)
return false; return false;
BlockFace location = new BlockFace(pos, side);
BlockFace location = new BlockFace(pos, side);
if (FluidPropagator.isOpenEnd(world, pos, side)) { if (FluidPropagator.isOpenEnd(world, pos, side)) {
if (previousSource.orElse(null) instanceof OpenEndedPipe) if (previousSource.orElse(null) instanceof OpenEndedPipe)
source = previousSource; source = previousSource;
@ -178,7 +181,7 @@ public class PipeConnection {
} }
FluidTransportBehaviour behaviour = FluidTransportBehaviour behaviour =
TileEntityBehaviour.get(world, pos.relative(side), FluidTransportBehaviour.TYPE); TileEntityBehaviour.get(world, relative, FluidTransportBehaviour.TYPE);
source = Optional.of(behaviour == null ? new FlowSource.Blocked(location) : new FlowSource.OtherPipe(location)); source = Optional.of(behaviour == null ? new FlowSource.Blocked(location) : new FlowSource.OtherPipe(location));
return true; return true;
} }

View file

@ -89,7 +89,9 @@ public class EncasedPipeBlock extends Block implements IWrenchable, ISpecialBloc
public void neighborChanged(BlockState state, World world, BlockPos pos, Block otherBlock, BlockPos neighborPos, public void neighborChanged(BlockState state, World world, BlockPos pos, Block otherBlock, BlockPos neighborPos,
boolean isMoving) { boolean isMoving) {
DebugPacketSender.sendNeighborsUpdatePacket(world, pos); DebugPacketSender.sendNeighborsUpdatePacket(world, pos);
Direction d = FluidPropagator.validateNeighbourChange(state, world, pos, otherBlock, neighborPos, isMoving); // calling getblockstate() as otherBlock param seems to contain the block which was replaced
Direction d = FluidPropagator.validateNeighbourChange(state, world, pos, world.getBlockState(neighborPos)
.getBlock(), neighborPos, isMoving);
if (d == null) if (d == null)
return; return;
if (!state.getValue(FACING_TO_PROPERTY_MAP.get(d))) if (!state.getValue(FACING_TO_PROPERTY_MAP.get(d)))