Merge branch 'mc1.16/dev' into pr/2123

This commit is contained in:
simibubi 2021-10-21 19:40:36 +02:00
commit d2d3c7f495
13 changed files with 129 additions and 29 deletions

View file

@ -10,6 +10,7 @@ import com.google.gson.GsonBuilder;
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour; import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
import com.simibubi.create.content.CreateItemGroup; import com.simibubi.create.content.CreateItemGroup;
import com.simibubi.create.content.contraptions.TorquePropagator; import com.simibubi.create.content.contraptions.TorquePropagator;
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineModifiers;
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController; import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes; import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes;
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler; import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
@ -98,6 +99,7 @@ public class Create {
AllMovementBehaviours.register(); AllMovementBehaviours.register();
AllWorldFeatures.register(); AllWorldFeatures.register();
AllEnchantments.register(); AllEnchantments.register();
FurnaceEngineModifiers.register();
AllConfigs.register(modLoadingContext); AllConfigs.register(modLoadingContext);
BlockSpoutingBehaviour.register(); BlockSpoutingBehaviour.register();

View file

@ -12,6 +12,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
@ -23,6 +24,7 @@ import net.minecraft.block.Blocks;
import net.minecraft.block.CocoaBlock; import net.minecraft.block.CocoaBlock;
import net.minecraft.block.CropsBlock; import net.minecraft.block.CropsBlock;
import net.minecraft.block.SugarCaneBlock; import net.minecraft.block.SugarCaneBlock;
import net.minecraft.block.SweetBerryBushBlock;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
@ -50,14 +52,16 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
@Nullable @Nullable
@Override @Override
public ActorInstance createInstance(MaterialManager<?> materialManager, PlacementSimulationWorld simulationWorld, MovementContext context) { public ActorInstance createInstance(MaterialManager<?> materialManager, PlacementSimulationWorld simulationWorld,
MovementContext context) {
return new HarvesterActorInstance(materialManager, simulationWorld, context); return new HarvesterActorInstance(materialManager, simulationWorld, context);
} }
@Override @Override
public void renderInContraption(MovementContext context, PlacementSimulationWorld renderWorld, public void renderInContraption(MovementContext context, PlacementSimulationWorld renderWorld,
ContraptionMatrices matrices, IRenderTypeBuffer buffers) { ContraptionMatrices matrices, IRenderTypeBuffer buffers) {
if (!Backend.getInstance().canUseInstancing()) if (!Backend.getInstance()
.canUseInstancing())
HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers); HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers);
} }
@ -87,7 +91,8 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
ItemStack item = ItemStack.EMPTY; ItemStack item = ItemStack.EMPTY;
float effectChance = 1; float effectChance = 1;
if (stateVisited.getBlock().is(BlockTags.LEAVES)) { if (stateVisited.getBlock()
.is(BlockTags.LEAVES)) {
item = new ItemStack(Items.SHEARS); item = new ItemStack(Items.SHEARS);
effectChance = .45f; effectChance = .45f;
} }
@ -95,7 +100,8 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
MutableBoolean seedSubtracted = new MutableBoolean(notCropButCuttable); MutableBoolean seedSubtracted = new MutableBoolean(notCropButCuttable);
BlockState state = stateVisited; BlockState state = stateVisited;
BlockHelper.destroyBlockAs(world, pos, null, item, effectChance, stack -> { BlockHelper.destroyBlockAs(world, pos, null, item, effectChance, stack -> {
if (!seedSubtracted.getValue() && stack.sameItem(new ItemStack(state.getBlock()))) { if (AllConfigs.SERVER.kinetics.harvesterReplants.get() && !seedSubtracted.getValue()
&& stack.sameItem(new ItemStack(state.getBlock()))) {
stack.shrink(1); stack.shrink(1);
seedSubtracted.setTrue(); seedSubtracted.setTrue();
} }
@ -106,23 +112,31 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
} }
private boolean isValidCrop(World world, BlockPos pos, BlockState state) { private boolean isValidCrop(World world, BlockPos pos, BlockState state) {
boolean harvestPartial = AllConfigs.SERVER.kinetics.harvestPartiallyGrown.get();
boolean replant = AllConfigs.SERVER.kinetics.harvesterReplants.get();
if (state.getBlock() instanceof CropsBlock) { if (state.getBlock() instanceof CropsBlock) {
CropsBlock crop = (CropsBlock) state.getBlock(); CropsBlock crop = (CropsBlock) state.getBlock();
if (!crop.isMaxAge(state)) if (harvestPartial)
return false; return state.getValue(crop.getAgeProperty()) != 0 || !replant;
return true; return crop.isMaxAge(state);
} }
if (state.getCollisionShape(world, pos) if (state.getCollisionShape(world, pos)
.isEmpty() || state.getBlock() instanceof CocoaBlock) { .isEmpty() || state.getBlock() instanceof CocoaBlock) {
for (Property<?> property : state.getProperties()) { for (Property<?> property : state.getProperties()) {
if (!(property instanceof IntegerProperty)) if (!(property instanceof IntegerProperty))
continue; continue;
IntegerProperty ageProperty = (IntegerProperty) property;
if (!property.getName() if (!property.getName()
.equals(BlockStateProperties.AGE_1.getName())) .equals(BlockStateProperties.AGE_1.getName()))
continue; continue;
if (((IntegerProperty) property).getPossibleValues() int age = state.getValue(ageProperty)
.size() - 1 != state.getValue((IntegerProperty) property) .intValue();
.intValue()) if (state.getBlock() instanceof SweetBerryBushBlock && age <= 1 && replant)
continue;
if (age == 0 && replant || !harvestPartial && (ageProperty.getPossibleValues()
.size() - 1 != age))
continue; continue;
return true; return true;
} }
@ -136,7 +150,8 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
return false; return false;
if (state.getBlock() instanceof SugarCaneBlock) if (state.getBlock() instanceof SugarCaneBlock)
return true; return true;
if (state.getBlock().is(BlockTags.LEAVES)) if (state.getBlock()
.is(BlockTags.LEAVES))
return true; return true;
if (state.getCollisionShape(world, pos) if (state.getCollisionShape(world, pos)
@ -161,6 +176,14 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
} }
private BlockState cutCrop(World world, BlockPos pos, BlockState state) { private BlockState cutCrop(World world, BlockPos pos, BlockState state) {
if (!AllConfigs.SERVER.kinetics.harvesterReplants.get()) {
if (state.getFluidState()
.isEmpty())
return Blocks.AIR.defaultBlockState();
return state.getFluidState()
.createLegacyBlock();
}
Block block = state.getBlock(); Block block = state.getBlock();
if (block instanceof CropsBlock) { if (block instanceof CropsBlock) {
CropsBlock crop = (CropsBlock) block; CropsBlock crop = (CropsBlock) block;
@ -171,18 +194,18 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
} }
if (block == Blocks.SUGAR_CANE || block instanceof AbstractPlantBlock) { if (block == Blocks.SUGAR_CANE || block instanceof AbstractPlantBlock) {
if (state.getFluidState() if (state.getFluidState()
.isEmpty()) .isEmpty())
return Blocks.AIR.defaultBlockState(); return Blocks.AIR.defaultBlockState();
return state.getFluidState() return state.getFluidState()
.createLegacyBlock(); .createLegacyBlock();
} }
if (state.getCollisionShape(world, pos) if (state.getCollisionShape(world, pos)
.isEmpty() || block instanceof CocoaBlock) { .isEmpty() || block instanceof CocoaBlock) {
for (Property<?> property : state.getProperties()) { for (Property<?> property : state.getProperties()) {
if (!(property instanceof IntegerProperty)) if (!(property instanceof IntegerProperty))
continue; continue;
if (!property.getName() if (!property.getName()
.equals(BlockStateProperties.AGE_1.getName())) .equals(BlockStateProperties.AGE_1.getName()))
continue; continue;
return state.setValue((IntegerProperty) property, Integer.valueOf(0)); return state.setValue((IntegerProperty) property, Integer.valueOf(0));
} }

View file

@ -0,0 +1,32 @@
package com.simibubi.create.content.contraptions.components.flywheel.engine;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraftforge.registries.IRegistryDelegate;
public class FurnaceEngineModifiers {
public final static FurnaceEngineModifiers INSTANCE = new FurnaceEngineModifiers();
protected Map<IRegistryDelegate<Block>, Float> blockModifiers = new HashMap<>();
public void register(IRegistryDelegate<Block> block, float modifier) {
this.blockModifiers.put(block, modifier);
}
public float getModifierOrDefault(BlockState state, float defaultValue) {
return blockModifiers.getOrDefault(state.getBlock().delegate, defaultValue);
}
public float getModifier(BlockState state) {
return getModifierOrDefault(state, 1f);
}
public static void register() {
INSTANCE.register(Blocks.BLAST_FURNACE.delegate, 2f);
}
}

View file

@ -25,7 +25,7 @@ public class FurnaceEngineTileEntity extends EngineTileEntity {
if (!(state.getBlock() instanceof AbstractFurnaceBlock)) if (!(state.getBlock() instanceof AbstractFurnaceBlock))
return; return;
float modifier = state.getBlock() == Blocks.BLAST_FURNACE ? 2 : 1; float modifier = FurnaceEngineModifiers.INSTANCE.getModifier(state);
boolean active = state.hasProperty(AbstractFurnaceBlock.LIT) && state.getValue(AbstractFurnaceBlock.LIT); boolean active = state.hasProperty(AbstractFurnaceBlock.LIT) && state.getValue(AbstractFurnaceBlock.LIT);
float speed = active ? 16 * modifier : 0; float speed = active ? 16 * modifier : 0;
float capacity = float capacity =

View file

@ -5,6 +5,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -33,7 +34,11 @@ public abstract class MovementBehaviour {
} }
public void dropItem(MovementContext context, ItemStack stack) { public void dropItem(MovementContext context, ItemStack stack) {
ItemStack remainder = ItemHandlerHelper.insertItem(context.contraption.inventory, stack, false); ItemStack remainder;
if (AllConfigs.SERVER.kinetics.moveItemsToStorage.get())
remainder = ItemHandlerHelper.insertItem(context.contraption.inventory, stack, false);
else
remainder = stack;
if (remainder.isEmpty()) if (remainder.isEmpty())
return; return;

View file

@ -29,14 +29,14 @@ public abstract class FluidTransportBehaviour extends TileEntityBehaviour {
public static BehaviourType<FluidTransportBehaviour> TYPE = new BehaviourType<>(); public static BehaviourType<FluidTransportBehaviour> TYPE = new BehaviourType<>();
enum UpdatePhase { public enum UpdatePhase {
WAIT_FOR_PUMPS, // Do not run Layer II logic while pumps could still be distributing pressure WAIT_FOR_PUMPS, // Do not run Layer II logic while pumps could still be distributing pressure
FLIP_FLOWS, // Do not cut any flows until all pipes had a chance to reverse them FLIP_FLOWS, // Do not cut any flows until all pipes had a chance to reverse them
IDLE; // Operate normally IDLE; // Operate normally
} }
Map<Direction, PipeConnection> interfaces; public Map<Direction, PipeConnection> interfaces;
UpdatePhase phase; public UpdatePhase phase;
public FluidTransportBehaviour(SmartTileEntity te) { public FluidTransportBehaviour(SmartTileEntity te) {
super(te); super(te);

View file

@ -11,6 +11,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.AllFluids; import com.simibubi.create.AllFluids;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler; import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler;
import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.fluid.FluidHelper; import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.BlockFace;
@ -214,6 +215,10 @@ public class OpenEndedPipe extends FlowSource {
.scheduleTick(outputPos, Fluids.WATER, 1); .scheduleTick(outputPos, Fluids.WATER, 1);
return true; return true;
} }
if (!AllConfigs.SERVER.fluids.placeFluidSourceBlocks.get())
return true;
world.setBlock(outputPos, fluid.getFluid() world.setBlock(outputPos, fluid.getFluid()
.defaultFluidState() .defaultFluidState()
.createLegacyBlock(), 3); .createLegacyBlock(), 3);

View file

@ -32,7 +32,7 @@ import net.minecraftforge.fml.DistExecutor;
public class PipeConnection { public class PipeConnection {
Direction side; public Direction side;
// Layer I // Layer I
Couple<Float> pressure; // [inbound, outward] Couple<Float> pressure; // [inbound, outward]

View file

@ -7,6 +7,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.fluid.FluidHelper; import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
@ -126,23 +127,25 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
int maxBlocks = maxBlocks(); int maxBlocks = maxBlocks();
boolean evaporate = world.dimensionType() boolean evaporate = world.dimensionType()
.ultraWarm() && fluid.is(FluidTags.WATER); .ultraWarm() && fluid.is(FluidTags.WATER);
boolean canPlaceSources = AllConfigs.SERVER.fluids.placeFluidSourceBlocks.get();
if ((!fillInfinite() && infinite) || evaporate) { if ((!fillInfinite() && infinite) || evaporate || !canPlaceSources) {
FluidState fluidState = world.getFluidState(rootPos); FluidState fluidState = world.getFluidState(rootPos);
boolean equivalentTo = fluidState.getType() boolean equivalentTo = fluidState.getType()
.isSame(fluid); .isSame(fluid);
if (!equivalentTo && !evaporate) if (!equivalentTo && !evaporate && canPlaceSources)
return false; return false;
if (simulate) if (simulate)
return true; return true;
playEffect(world, null, fluid, false); playEffect(world, root, fluid, false);
if (evaporate) { if (evaporate) {
int i = root.getX(); int i = root.getX();
int j = root.getY(); int j = root.getY();
int k = root.getZ(); int k = root.getZ();
world.playSound(null, i, j, k, SoundEvents.FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, world.playSound(null, i, j, k, SoundEvents.FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F,
2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F);
} } else if (!canPlaceSources)
AllTriggers.triggerForNearbyPlayers(AllTriggers.HOSE_PULLEY, world, tileEntity.getBlockPos(), 8);
return true; return true;
} }

View file

@ -12,6 +12,8 @@ public class CFluids extends ConfigBase {
public final ConfigBool fillInfinite = b(false, "fillInfinite", Comments.fillInfinite); public final ConfigBool fillInfinite = b(false, "fillInfinite", Comments.fillInfinite);
public final ConfigInt hosePulleyRange = i(128, 1, "hosePulleyRange", Comments.blocks, Comments.hosePulleyRange); public final ConfigInt hosePulleyRange = i(128, 1, "hosePulleyRange", Comments.blocks, Comments.hosePulleyRange);
public ConfigBool placeFluidSourceBlocks = b(true, "placeFluidSourceBlocks", Comments.placeFluidSourceBlocks);
@Override @Override
public String getName() { public String getName() {
return "fluids"; return "fluids";
@ -30,6 +32,7 @@ public class CFluids extends ConfigBase {
static String hosePulleyBlockThreshold = static String hosePulleyBlockThreshold =
"The minimum amount of fluid blocks the hose pulley needs to find before deeming it an infinite source."; "The minimum amount of fluid blocks the hose pulley needs to find before deeming it an infinite source.";
static String fillInfinite = "Whether hose pulleys should continue filling up above-threshold sources"; static String fillInfinite = "Whether hose pulleys should continue filling up above-threshold sources";
static String placeFluidSourceBlocks = "Whether open-ended pipes and hose pulleys should be allowed to place fluid sources";
} }
} }

View file

@ -40,6 +40,9 @@ public class CKinetics extends ConfigBase {
e(ContraptionMovementSetting.NO_PICKUP, "movableSpawners", Comments.spawnerMovement); e(ContraptionMovementSetting.NO_PICKUP, "movableSpawners", Comments.spawnerMovement);
public final ConfigEnum<ContraptionMovementSetting> obsidianMovement = public final ConfigEnum<ContraptionMovementSetting> obsidianMovement =
e(ContraptionMovementSetting.UNMOVABLE, "movableObsidian", Comments.obsidianMovement); e(ContraptionMovementSetting.UNMOVABLE, "movableObsidian", Comments.obsidianMovement);
public ConfigBool moveItemsToStorage = b(true, "moveItemsToStorage", Comments.moveItemsToStorage);
public ConfigBool harvestPartiallyGrown = b(false, "harvestPartiallyGrown", Comments.harvestPartiallyGrown);
public ConfigBool harvesterReplants = b(true, "harvesterReplants", Comments.harvesterReplants);
public final CStress stressValues = nested(1, CStress::new, Comments.stress); public final CStress stressValues = nested(1, CStress::new, Comments.stress);
@ -76,6 +79,10 @@ public class CKinetics extends ConfigBase {
static String maxPistonPoles = "Maximum amount of extension poles behind a Mechanical Piston."; static String maxPistonPoles = "Maximum amount of extension poles behind a Mechanical Piston.";
static String maxRopeLength = "Max length of rope available off a Rope Pulley."; static String maxRopeLength = "Max length of rope available off a Rope Pulley.";
static String maxCartCouplingLength = "Maximum allowed distance of two coupled minecarts."; static String maxCartCouplingLength = "Maximum allowed distance of two coupled minecarts.";
static String moveItemsToStorage =
"Whether items mined or harvested by contraptions should be placed in their mounted storage.";
static String harvestPartiallyGrown = "Whether harvesters should break crops that aren't fully grown.";
static String harvesterReplants = "Whether harvesters should replant crops after harvesting.";
static String stats = "Configure speed/capacity levels for requirements and indicators."; static String stats = "Configure speed/capacity levels for requirements and indicators.";
static String rpm = "[in Revolutions per Minute]"; static String rpm = "[in Revolutions per Minute]";
static String su = "[in Stress Units]"; static String su = "[in Stress Units]";

View file

@ -0,0 +1,18 @@
package com.simibubi.create.foundation.utility.worldWrappers;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.listener.IChunkStatusListener;
public class DummyStatusListener implements IChunkStatusListener {
@Override
public void updateSpawnPos(ChunkPos p_219509_1_) {}
@Override
public void onStatusChange(ChunkPos p_219508_1_, ChunkStatus p_219508_2_) {}
@Override
public void stop() {}
}

View file

@ -37,8 +37,10 @@ public class WrappedServerWorld extends ServerWorld {
protected World world; protected World world;
public WrappedServerWorld(World world) { public WrappedServerWorld(World world) {
// Replace null with world.getChunkProvider().chunkManager.progressListener ? We had null in 1.15 super(world.getServer(), Util.backgroundExecutor(), getLevelSaveFromWorld(world),
super(world.getServer(), Util.backgroundExecutor(), getLevelSaveFromWorld(world), (IServerWorldInfo) world.getLevelData(), world.dimension(), world.dimensionType(), null, ((ServerChunkProvider) world.getChunkSource()).getGenerator(), world.isDebug(), world.getBiomeManager().biomeZoomSeed, Collections.EMPTY_LIST, false); //, world.field_25143); (IServerWorldInfo) world.getLevelData(), world.dimension(), world.dimensionType(),
new DummyStatusListener(), ((ServerChunkProvider) world.getChunkSource()).getGenerator(), world.isDebug(),
world.getBiomeManager().biomeZoomSeed, Collections.emptyList(), false);
this.world = world; this.world = world;
} }