Merge branch 'mc1.15/dev' of https://github.com/Creators-of-Create/Create into mc1.15/dev

This commit is contained in:
simibubi 2020-10-10 21:15:48 +02:00
commit 22ed233969
17 changed files with 314 additions and 146 deletions

View file

@ -47,7 +47,6 @@ public class AllShapes {
.forDirectional(),
CRANK = shape(5, 0, 5, 11, 6, 11).add(1, 3, 1, 15, 8, 15)
.forDirectional(),
VALVE_HANDLE = shape(1, 0, 1, 15, 5, 15).forDirectional(),
CART_ASSEMBLER = shape(0, 12, 0, 16, 16, 16).add(-2, 0, 1, 18, 14, 15)
.forHorizontalAxis(),
CART_ASSEMBLER_PLAYER_COLLISION = shape(0, 0, 1, 16, 16, 15).forHorizontalAxis(),

View file

@ -21,6 +21,7 @@ import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.resources.I18n;
import net.minecraft.nbt.CompoundNBT;
@ -145,11 +146,15 @@ public abstract class KineticTileEntity extends SmartTileEntity
}
public float calculateAddedStressCapacity() {
float capacity = (float) AllConfigs.SERVER.kinetics.stressValues.getCapacityOf(getBlockState().getBlock());
float capacity = (float) AllConfigs.SERVER.kinetics.stressValues.getCapacityOf(getStressConfigKey());
this.lastCapacityProvided = capacity;
return capacity;
}
protected Block getStressConfigKey() {
return getBlockState().getBlock();
}
public float calculateStressApplied() {
float impact = (float) AllConfigs.SERVER.kinetics.stressValues.getImpactOf(getBlockState().getBlock());
this.lastStressApplied = impact;

View file

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import com.simibubi.create.AllTags;
import com.simibubi.create.foundation.config.StressConfigDefaults;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.data.SharedProperties;
import com.tterrag.registrate.util.entry.BlockEntry;
@ -28,7 +27,6 @@ public class AllValveHandles {
.blockstate((c, p) -> p.directionalBlock(c.get(), p.models()
.withExistingParent(type + "_valve_handle", p.modLoc("block/valve_handle"))
.texture("3", p.modLoc("block/valve_handle/valve_handle_" + type))))
.transform(StressConfigDefaults.setCapacity(32.0))
.tag(AllTags.AllBlockTags.BRITTLE.tag)
.simpleItem()
.register();

View file

@ -6,6 +6,7 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.config.AllConfigs;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
@ -61,6 +62,7 @@ public class HandCrankBlock extends DirectionalKineticBlock implements ITE<HandC
return ActionResultType.PASS;
withTileEntityDo(worldIn, pos, te -> te.turn(player.isSneaking()));
player.addExhaustion(getRotationSpeed() * AllConfigs.SERVER.kinetics.crankHungerMultiplier.getF());
return ActionResultType.SUCCESS;
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions.components.crank;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity;
import net.minecraft.block.Block;
@ -67,4 +68,8 @@ public class HandCrankTileEntity extends GeneratingKineticTileEntity {
}
}
@Override
protected Block getStressConfigKey() {
return AllBlocks.HAND_CRANK.get();
}
}

View file

@ -3,16 +3,10 @@ package com.simibubi.create.content.contraptions.components.crank;
import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllShapes;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -32,11 +26,6 @@ public class ValveHandleBlock extends HandCrankBlock {
super.fillItemGroup(group, p_149666_2_);
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return AllShapes.VALVE_HANDLE.get(state.get(FACING));
}
@Override
@OnlyIn(Dist.CLIENT)
public AllBlockPartials getRenderedHandle() {

View file

@ -23,7 +23,6 @@ import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.monster.EndermanEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.DamageSource;
import net.minecraft.util.Direction;
import net.minecraft.util.SoundCategory;
@ -41,12 +40,12 @@ import net.minecraft.world.World;
public class AirCurrent {
private static DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled()
private static final DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled()
.setFireDamage();
private static DamageSource damageSourceLava = new DamageSource("create.fan_lava").setDifficultyScaled()
private static final DamageSource damageSourceLava = new DamageSource("create.fan_lava").setDifficultyScaled()
.setFireDamage();
public final EncasedFanTileEntity source;
public final IAirCurrentSource source;
public AxisAlignedBB bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
public List<AirCurrentSegment> segments = new ArrayList<>();
public Direction direction;
@ -57,19 +56,21 @@ public class AirCurrent {
new ArrayList<>();
protected List<Entity> caughtEntities = new ArrayList<>();
public AirCurrent(EncasedFanTileEntity source) {
public AirCurrent(IAirCurrentSource source) {
this.source = source;
}
public void tick() {
World world = source.getWorld();
if (direction == null)
rebuild();
World world = source.getAirCurrentWorld();
Direction facing = direction;
if (world.isRemote) {
if (world != null && world.isRemote) {
float offset = pushing ? 0.5f : maxDistance + .5f;
Vec3d pos = VecHelper.getCenterOf(source.getPos())
Vec3d pos = VecHelper.getCenterOf(source.getAirCurrentPos())
.add(new Vec3d(facing.getDirectionVec()).scale(offset));
if (world.rand.nextFloat() < AllConfigs.CLIENT.fanParticleDensity.get())
world.addParticle(new AirFlowParticleData(source.getPos()), pos.x, pos.y, pos.z, 0, 0, 0);
world.addParticle(new AirFlowParticleData(source.getAirCurrentPos()), pos.x, pos.y, pos.z, 0, 0, 0);
}
for (Iterator<Entity> iterator = caughtEntities.iterator(); iterator.hasNext();) {
@ -80,7 +81,7 @@ public class AirCurrent {
continue;
}
Vec3d center = VecHelper.getCenterOf(source.getPos());
Vec3d center = VecHelper.getCenterOf(source.getAirCurrentPos());
Vec3i flow = (pushing ? facing : facing.getOpposite()).getDirectionVec();
float sneakModifier = entity.isSneaking() ? 4096f : 512f;
@ -157,17 +158,16 @@ public class AirCurrent {
return;
}
direction = source.getBlockState()
.get(BlockStateProperties.FACING);
direction = source.getAirflowOriginSide();
pushing = source.getAirFlowDirection() == direction;
maxDistance = source.getMaxDistance();
World world = source.getWorld();
BlockPos start = source.getPos();
World world = source.getAirCurrentWorld();
BlockPos start = source.getAirCurrentPos();
float max = this.maxDistance;
Direction facing = direction;
Vec3d directionVec = new Vec3d(facing.getDirectionVec());
maxDistance = getFlowLimit(world, start, max, facing);
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
// if (source instanceof EncasedFanTileEntity) // debug
maxDistance = getFlowLimit(world, start, max, direction);
// Determine segments with transported fluids/gases
AirCurrentSegment currentSegment = new AirCurrentSegment();
@ -266,13 +266,13 @@ public class AirCurrent {
public void findEntities() {
caughtEntities.clear();
caughtEntities = source.getWorld()
caughtEntities = source.getAirCurrentWorld()
.getEntitiesWithinAABBExcludingEntity(null, bounds);
}
public void findAffectedHandlers() {
World world = source.getWorld();
BlockPos start = source.getPos();
World world = source.getAirCurrentWorld();
BlockPos start = source.getAirCurrentPos();
affectedItemHandlers.clear();
for (int i = 0; i < maxDistance + 1; i++) {
Type type = getSegmentAt(i);

View file

@ -5,17 +5,22 @@ import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.CKinetics;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
import javax.annotation.Nullable;
@MethodsReturnNonnullByDefault
public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements IAirCurrentSource {
public AirCurrent airCurrent;
protected int airCurrentUpdateCooldown;
@ -88,15 +93,29 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
return true;
}
public float getMaxDistance() {
float speed = Math.abs(this.getSpeed());
CKinetics config = AllConfigs.SERVER.kinetics;
float distanceFactor = Math.min(speed / config.fanRotationArgmax.get(), 1);
float pushDistance = MathHelper.lerp(distanceFactor, 3, config.fanPushDistance.get());
float pullDistance = MathHelper.lerp(distanceFactor, 3f, config.fanPullDistance.get());
return this.getSpeed() > 0 ? pushDistance : pullDistance;
@Override
public AirCurrent getAirCurrent() {
return airCurrent;
}
@Nullable
@Override
public World getAirCurrentWorld() {
return world;
}
@Override
public BlockPos getAirCurrentPos() {
return pos;
}
@Override
public Direction getAirflowOriginSide() {
return this.getBlockState()
.get(EncasedFanBlock.FACING);
}
@Override
public Direction getAirFlowDirection() {
float speed = getSpeed();
if (speed == 0)
@ -106,6 +125,11 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
return speed > 0 ? facing : facing.getOpposite();
}
@Override
public boolean isSourceRemoved() {
return removed;
}
@Override
public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed);

View file

@ -0,0 +1,40 @@
package com.simibubi.create.content.contraptions.components.fan;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.CKinetics;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import javax.annotation.Nullable;
@MethodsReturnNonnullByDefault
public interface IAirCurrentSource {
@Nullable
AirCurrent getAirCurrent();
@Nullable
World getAirCurrentWorld();
BlockPos getAirCurrentPos();
float getSpeed();
Direction getAirflowOriginSide();
@Nullable
Direction getAirFlowDirection();
default float getMaxDistance() {
float speed = Math.abs(this.getSpeed());
CKinetics config = AllConfigs.SERVER.kinetics;
float distanceFactor = Math.min(speed / config.fanRotationArgmax.get(), 1);
float pushDistance = MathHelper.lerp(distanceFactor, 3, config.fanPushDistance.get());
float pullDistance = MathHelper.lerp(distanceFactor, 3f, config.fanPullDistance.get());
return this.getSpeed() > 0 ? pushDistance : pullDistance;
}
boolean isSourceRemoved();
}

View file

@ -123,19 +123,18 @@ public class NozzleTileEntity extends SmartTileEntity {
private float calcRange() {
TileEntity te = world.getTileEntity(fanPos);
if (!(te instanceof EncasedFanTileEntity))
if (!(te instanceof IAirCurrentSource))
return 0;
EncasedFanTileEntity fan = (EncasedFanTileEntity) te;
if (fan.isGenerator)
IAirCurrentSource source = (IAirCurrentSource) te;
if (source instanceof EncasedFanTileEntity && ((EncasedFanTileEntity) source).isGenerator)
return 0;
if (fan.airCurrent == null)
if (source.getAirCurrent() == null)
return 0;
if (fan.getSpeed() == 0)
if (source.getSpeed() == 0)
return 0;
pushing = fan.getAirFlowDirection() == fan.getBlockState()
.get(EncasedFanBlock.FACING);
return fan.getMaxDistance();
pushing = source.getAirFlowDirection() == source.getAirflowOriginSide();
return source.getMaxDistance();
}
@Override

View file

@ -1,7 +1,7 @@
package com.simibubi.create.content.contraptions.particle;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
import com.simibubi.create.content.contraptions.components.fan.IAirCurrentSource;
import com.simibubi.create.content.logistics.InWorldProcessing;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -21,11 +21,13 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
public class AirFlowParticle extends SimpleAnimatedParticle {
private EncasedFanTileEntity source;
private final IAirCurrentSource source;
protected AirFlowParticle(World world, EncasedFanTileEntity source, double x, double y, double z,
protected AirFlowParticle(World world, IAirCurrentSource source, double x, double y, double z,
IAnimatedSprite sprite) {
super(world, x, y, z, sprite, world.rand.nextFloat() * .5f);
this.source = source;
@ -41,13 +43,14 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
setAlphaF(.25f);
}
@Nonnull
public IParticleRenderType getRenderType() {
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
}
@Override
public void tick() {
if (source == null || source.isRemoved()) {
if (source == null || source.isSourceRemoved()) {
dissipate();
return;
}
@ -57,24 +60,24 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
if (this.age++ >= this.maxAge) {
this.setExpired();
} else {
if (source.airCurrent == null || !source.airCurrent.bounds.grow(.25f).contains(posX, posY, posZ)) {
if (source.getAirCurrent() == null || !source.getAirCurrent().bounds.grow(.25f).contains(posX, posY, posZ)) {
dissipate();
return;
}
Vec3d directionVec = new Vec3d(source.airCurrent.direction.getDirectionVec());
Vec3d directionVec = new Vec3d(source.getAirCurrent().direction.getDirectionVec());
Vec3d motion = directionVec.scale(1 / 8f);
if (!source.airCurrent.pushing)
if (!source.getAirCurrent().pushing)
motion = motion.scale(-1);
double distance = new Vec3d(posX, posY, posZ).subtract(VecHelper.getCenterOf(source.getPos()))
double distance = new Vec3d(posX, posY, posZ).subtract(VecHelper.getCenterOf(source.getAirCurrentPos()))
.mul(directionVec).length() - .5f;
if (distance > source.airCurrent.maxDistance + 1 || distance < -.25f) {
if (distance > source.getAirCurrent().maxDistance + 1 || distance < -.25f) {
dissipate();
return;
}
motion = motion.scale(source.airCurrent.maxDistance - (distance - 1f)).scale(.5f);
selectSprite((int) MathHelper.clamp((distance / source.airCurrent.maxDistance) * 8 + world.rand.nextInt(4),
motion = motion.scale(source.getAirCurrent().maxDistance - (distance - 1f)).scale(.5f);
selectSprite((int) MathHelper.clamp((distance / source.getAirCurrent().maxDistance) * 8 + world.rand.nextInt(4),
0, 7));
morphType(distance);
@ -84,8 +87,8 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
motionZ = motion.z;
if (this.onGround) {
this.motionX *= (double) 0.7F;
this.motionZ *= (double) 0.7F;
this.motionX *= 0.7;
this.motionZ *= 0.7;
}
this.move(this.motionX, this.motionY, this.motionZ);
@ -94,7 +97,9 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
}
public void morphType(double distance) {
InWorldProcessing.Type type = source.airCurrent.getSegmentAt((float) distance);
if(source.getAirCurrent() == null)
return;
InWorldProcessing.Type type = source.getAirCurrent().getSegmentAt((float) distance);
if (type == InWorldProcessing.Type.SPLASHING) {
setColor(ColorHelper.mixColors(0x4499FF, 0x2277FF, world.rand.nextFloat()));
@ -162,9 +167,9 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
public Particle makeParticle(AirFlowParticleData data, World worldIn, double x, double y, double z,
double xSpeed, double ySpeed, double zSpeed) {
TileEntity te = worldIn.getTileEntity(new BlockPos(data.posX, data.posY, data.posZ));
if (!(te instanceof EncasedFanTileEntity))
if (!(te instanceof IAirCurrentSource))
te = null;
return new AirFlowParticle(worldIn, (EncasedFanTileEntity) te, x, y, z, this.spriteSet);
return new AirFlowParticle(worldIn, (IAirCurrentSource) te, x, y, z, this.spriteSet);
}
}

View file

@ -411,7 +411,7 @@ public class BeltInventory {
if (Math.abs(position - transforted.beltPosition) >= maxDistanceToPosition)
continue;
TransportedResult result = processFunction.apply(transforted);
if (result.didntChangeFrom(stackBefore))
if (result == null|| result.didntChangeFrom(stackBefore))
continue;
dirty = true;

View file

@ -43,6 +43,8 @@ import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import javax.annotation.Nullable;
public class InWorldProcessing {
public static class SplashingInv extends RecipeWrapper {
@ -295,8 +297,8 @@ public class InWorldProcessing {
return stacks;
}
public static void spawnParticlesForProcessing(World world, Vec3d vec, Type type) {
if (!world.isRemote)
public static void spawnParticlesForProcessing(@Nullable World world, Vec3d vec, Type type) {
if (world == null || !world.isRemote)
return;
if (world.rand.nextInt(8) != 0)
return;

View file

@ -1,16 +1,11 @@
package com.simibubi.create.content.logistics.block.chute;
import java.util.LinkedList;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Predicates;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.fan.AirCurrent;
import com.simibubi.create.content.contraptions.components.fan.EncasedFanBlock;
import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
import com.simibubi.create.content.contraptions.components.fan.IAirCurrentSource;
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.contraptions.particle.AirParticleData;
import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
@ -28,7 +23,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemS
import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.item.ItemEntity;
@ -45,13 +40,23 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInformation {
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.LinkedList;
import java.util.List;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInformation, IAirCurrentSource {
public AirCurrent airCurrent;
float pull;
float push;
@ -82,9 +87,12 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
capAbove = LazyOptional.empty();
capBelow = LazyOptional.empty();
bottomPullDistance = 0;
airCurrent = new AirCurrent(this);
updateAirFlow = true;
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
@ -126,10 +134,9 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
canPickUpItems = canDirectlyInsert();
float itemMotion = getItemMotion();
if (itemMotion != 0 && world.isRemote)
if (itemMotion != 0 && world != null && world.isRemote)
spawnParticles(itemMotion);
if (itemMotion > 0)
tickAirStreamFromBelow(itemMotion);
tickAirStreams(itemMotion);
if (item.isEmpty()) {
if (itemMotion < 0)
@ -166,30 +173,64 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
itemPosition.set(nextOffset);
}
private void tickAirStreamFromBelow(float itemSpeed) {
if (world.isRemote)
return;
private void updateAirFlow(float itemSpeed) {
updateAirFlow = false;
airCurrent.rebuild();
if (itemSpeed > 0 && world != null && !world.isRemote) {
float speed = pull - push;
beltBelow = null;
if (airCurrentUpdateCooldown-- <= 0) {
airCurrentUpdateCooldown = AllConfigs.SERVER.kinetics.fanBlockCheckRate.get();
updateAirFlow = true;
}
float maxPullDistance;
if (speed >= 128)
maxPullDistance = 3;
else if (speed >= 64)
maxPullDistance = 2;
else if (speed >= 32)
maxPullDistance = 1;
else
maxPullDistance = MathHelper.lerp(speed / 32, 0, 1);
if (bottomPullDistance > 0 && getItem().isEmpty() && entitySearchCooldown-- <= 0) {
entitySearchCooldown = 5;
Vec3d center = VecHelper.getCenterOf(pos);
AxisAlignedBB searchArea =
new AxisAlignedBB(center.add(0, -bottomPullDistance - 0.5, 0), center.add(0, -0.5, 0)).grow(.45f);
for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, searchArea)) {
setItem(itemEntity.getItem()
.copy(),
(float) (itemEntity.getBoundingBox()
.getCenter().y - pos.getY()));
itemEntity.remove();
if (AllBlocks.CHUTE.has(world.getBlockState(pos.down())))
maxPullDistance = 0;
float flowLimit = maxPullDistance;
if (flowLimit > 0)
flowLimit = AirCurrent.getFlowLimit(world, pos, maxPullDistance, Direction.DOWN);
for (int i = 1; i <= flowLimit + 1; i++) {
TransportedItemStackHandlerBehaviour behaviour =
TileEntityBehaviour.get(world, pos.down(i), TransportedItemStackHandlerBehaviour.TYPE);
if (behaviour == null)
continue;
beltBelow = behaviour;
beltBelowOffset = i - 1;
break;
}
this.bottomPullDistance = flowLimit;
}
sendData();
}
private void findEntities(float itemSpeed) {
if (getSpeed() != 0)
airCurrent.findEntities();
if (bottomPullDistance <= 0 && !getItem().isEmpty() || itemSpeed <= 0 || world == null || world.isRemote)
return;
Vec3d center = VecHelper.getCenterOf(pos);
AxisAlignedBB searchArea =
new AxisAlignedBB(center.add(0, -bottomPullDistance - 0.5, 0), center.add(0, -0.5, 0)).grow(.45f);
for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, searchArea)) {
setItem(itemEntity.getItem()
.copy(),
(float) (itemEntity.getBoundingBox()
.getCenter().y - pos.getY()));
itemEntity.remove();
break;
}
}
private void extractFromBelt(float itemSpeed) {
if (itemSpeed <= 0 || world == null || world.isRemote)
return;
if (getItem().isEmpty() && beltBelow != null) {
beltBelow.handleCenteredProcessingOnAllItems(.5f, ts -> {
if (getItem().isEmpty()) {
@ -199,46 +240,26 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
return TransportedResult.doNothing();
});
}
}
if (!updateAirFlow)
return;
float speed = pull - push;
float flowLimit = 0;
updateAirFlow = false;
beltBelow = null;
float maxPullDistance;
if (speed >= 128)
maxPullDistance = 3;
else if (speed >= 64)
maxPullDistance = 2;
else if (speed >= 32)
maxPullDistance = 1;
else
maxPullDistance = MathHelper.lerp(speed / 32, 0, 1);
if (AllBlocks.CHUTE.has(world.getBlockState(pos.down())))
maxPullDistance = 0;
flowLimit = maxPullDistance;
if (flowLimit > 0)
flowLimit = AirCurrent.getFlowLimit(world, pos, maxPullDistance, Direction.DOWN);
for (int i = 1; i <= flowLimit + 1; i++) {
TransportedItemStackHandlerBehaviour behaviour =
TileEntityBehaviour.get(world, pos.down(i), TransportedItemStackHandlerBehaviour.TYPE);
if (behaviour == null)
continue;
beltBelow = behaviour;
beltBelowOffset = i - 1;
break;
private void tickAirStreams(float itemSpeed) {
if (!world.isRemote && airCurrentUpdateCooldown-- <= 0) {
airCurrentUpdateCooldown = AllConfigs.SERVER.kinetics.fanBlockCheckRate.get();
updateAirFlow = true;
}
if (bottomPullDistance == flowLimit)
return;
if (updateAirFlow) {
updateAirFlow(itemSpeed);
}
this.bottomPullDistance = flowLimit;
sendData();
if (entitySearchCooldown-- <= 0) {
entitySearchCooldown = 5;
findEntities(itemSpeed);
}
extractFromBelt(itemSpeed);
if (getSpeed() != 0)
airCurrent.tick();
}
public void blockBelowChanged() {
@ -246,6 +267,9 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
private void spawnParticles(float itemMotion) {
// todo: reduce the amount of particles
if (world == null)
return;
BlockState blockState = getBlockState();
boolean up = itemMotion > 0;
float absMotion = up ? itemMotion : -itemMotion;
@ -276,6 +300,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
private void spawnAirFlow(float verticalStart, float verticalEnd, float motion, float drag) {
if (world == null)
return;
AirParticleData airParticleData = new AirParticleData(drag, motion);
Vec3d origin = new Vec3d(pos);
float xOff = Create.random.nextFloat() * .5f + .25f;
@ -292,7 +318,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
capAbove = grabCapability(Direction.UP);
if (capAbove.isPresent())
item =
ItemHelper.extract(capAbove.orElse(null), Predicates.alwaysTrue(), ExtractionCountMode.UPTO, 16, false);
ItemHelper.extract(capAbove.orElse(null), stack -> true, ExtractionCountMode.UPTO, 16, false);
}
private void handleInputFromBelow() {
@ -300,7 +326,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
capBelow = grabCapability(Direction.DOWN);
if (capBelow.isPresent())
item =
ItemHelper.extract(capBelow.orElse(null), Predicates.alwaysTrue(), ExtractionCountMode.UPTO, 16, false);
ItemHelper.extract(capBelow.orElse(null), stack -> true, ExtractionCountMode.UPTO, 16, false);
}
private boolean handleDownwardOutput(boolean simulate) {
@ -318,7 +344,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
// Diagonal chutes can only insert into other chutes
if (direction.getAxis()
if (world == null || direction.getAxis()
.isHorizontal())
return false;
@ -433,6 +459,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
private LazyOptional<IItemHandler> grabCapability(Direction side) {
BlockPos pos = this.pos.offset(side);
if (world == null)
return LazyOptional.empty();
TileEntity te = world.getTileEntity(pos);
if (te == null || te instanceof ChuteTileEntity)
return LazyOptional.empty();
@ -476,8 +504,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
push = compound.getFloat("Push");
bottomPullDistance = compound.getFloat("BottomAirFlowDistance");
super.read(compound, clientPacket);
if (clientPacket)
airCurrent.rebuild();
if (hasWorld() && world.isRemote && !previousItem.equals(item, false) && !item.isEmpty()) {
if (hasWorld() && world != null && world.isRemote && !previousItem.equals(item, false) && !item.isEmpty()) {
if (world.rand.nextInt(3) != 0)
return;
Vec3d p = VecHelper.getCenterOf(pos);
@ -500,7 +530,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
public void onRemoved(BlockState chuteState) {
ChuteTileEntity targetChute = getTargetChute(chuteState);
List<ChuteTileEntity> inputChutes = getInputChutes();
if (!item.isEmpty())
if (!item.isEmpty() && world != null)
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), item);
remove();
if (targetChute != null) {
@ -569,6 +599,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
protected float calculatePush(int branchCount) {
if (world == null)
return 0;
BlockState blockStateBelow = world.getBlockState(pos.down());
if (AllBlocks.ENCASED_FAN.has(blockStateBelow) && blockStateBelow.get(EncasedFanBlock.FACING) == Direction.UP) {
TileEntity te = world.getTileEntity(pos.down());
@ -586,6 +618,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
@Nullable
private ChuteTileEntity getTargetChute(BlockState state) {
if (world == null)
return null;
Direction targetDirection = state.get(ChuteBlock.FACING);
BlockPos chutePos = pos.down();
if (targetDirection.getAxis()
@ -613,7 +647,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
@Nullable
private ChuteTileEntity getInputChute(Direction direction) {
if (direction == Direction.DOWN)
if (world == null || direction == Direction.DOWN)
return null;
direction = direction.getOpposite();
BlockPos chutePos = pos.up();
@ -638,7 +672,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
public <T> LazyOptional<T> getCapability(Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return lazyHandler.cast();
return super.getCapability(cap, side);
@ -648,4 +682,47 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
return item;
}
@Override
@Nullable
public AirCurrent getAirCurrent() {
return airCurrent;
}
@Nullable
@Override
public World getAirCurrentWorld() {
return world;
}
@Override
public BlockPos getAirCurrentPos() {
return pos;
}
@Override
public float getSpeed() {
if (getBlockState().get(ChuteBlock.SHAPE) == Shape.NORMAL && getBlockState().get(ChuteBlock.FACING) != Direction.DOWN)
return 0;
return pull + push;
}
@Override
@Nullable
public Direction getAirFlowDirection() {
float speed = getSpeed();
if (speed == 0)
return null;
return speed > 0 ? Direction.UP : Direction.DOWN;
}
@Override
public boolean isSourceRemoved() {
return removed;
}
@Override
public Direction getAirflowOriginSide() {
return world != null && !(world.getTileEntity(pos.down()) instanceof IAirCurrentSource)
&& getBlockState().get(ChuteBlock.FACING) == Direction.DOWN ? Direction.DOWN : Direction.UP;
}
}

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
@ -28,6 +29,11 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class DepotBlock extends Block implements ITE<DepotTileEntity> {
public DepotBlock(Properties p_i48440_1_) {
@ -130,4 +136,18 @@ public class DepotBlock extends Block implements ITE<DepotTileEntity> {
itemEntity.remove();
}
@Override
public boolean hasComparatorInputOverride(BlockState state) {
return true;
}
@Override
public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) {
try {
return ItemHelper.calcRedstoneFromInventory(getTileEntity(worldIn, pos).itemHandler);
} catch (TileEntityException ignored) {
}
return 0;
}
}

View file

@ -5,6 +5,7 @@ import java.util.function.Function;
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.content.logistics.InWorldProcessing;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
@ -177,7 +178,7 @@ public class DepotTileEntity extends SmartTileEntity {
TransportedItemStack transportedItemStack = heldItem;
ItemStack stackBefore = transportedItemStack.stack.copy();
TransportedResult result = processFunction.apply(transportedItemStack);
if (result.didntChangeFrom(stackBefore))
if (result == null || result.didntChangeFrom(stackBefore))
return;
dirty = true;

View file

@ -12,6 +12,7 @@ public class CKinetics extends ConfigBase {
public ConfigEnum<DeployerAggroSetting> ignoreDeployerAttacks =
e(DeployerAggroSetting.CREEPERS, "ignoreDeployerAttacks", Comments.ignoreDeployerAttacks);
public ConfigInt kineticValidationFrequency = i(60, 5, "kineticValidationFrequency", Comments.kineticValidationFrequency);
public ConfigFloat crankHungerMultiplier = f(.01f, 0, 1, "crankHungerMultiplier", Comments.crankHungerMultiplier);
public ConfigGroup fan = group(1, "encasedFan", "Encased Fan");
public ConfigInt fanPushDistance = i(20, 5, "fanPushDistance", Comments.fanPushDistance);
@ -55,6 +56,7 @@ public class CKinetics extends ConfigBase {
static String fanRotationArgmax = "Rotation speed at which the maximum stats of fans are reached.";
static String generatingFanSpeed = "Rotation speed generated by a vertical fan above fire.";
static String inWorldProcessingTime = "Game ticks required for a Fan-based processing recipe to take effect.";
static String crankHungerMultiplier = "multiplier used for calculating exhaustion from speed when a crank is turned.";
static String maxBlocksMoved = "Maximum amount of blocks in a structure movable by Pistons, Bearings or other means.";
static String maxChassisRange = "Maximum value of a chassis attachment range.";
static String maxPistonPoles = "Maximum amount of extension poles behind a Mechanical Piston.";