mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Chute and Air. This took way too long.
This commit is contained in:
parent
6649ae8d28
commit
71ebdf044b
12 changed files with 241 additions and 123 deletions
|
@ -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;
|
||||
|
@ -402,7 +407,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
|
||||
boolean added = false;
|
||||
float stressAtBase = calculateStressApplied();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.components.crank;
|
||||
|
||||
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;
|
||||
|
@ -27,7 +26,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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,14 +56,16 @@ 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() {
|
||||
if (direction == null)
|
||||
rebuild();
|
||||
World world = source.getWorld();
|
||||
Direction facing = direction;
|
||||
if (world.isRemote) {
|
||||
if (world != null && world.isRemote) {
|
||||
float offset = pushing ? 0.5f : maxDistance + .5f;
|
||||
Vec3d pos = VecHelper.getCenterOf(source.getPos())
|
||||
.add(new Vec3d(facing.getDirectionVec()).scale(offset));
|
||||
|
@ -160,17 +161,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();
|
||||
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();
|
||||
|
|
|
@ -5,17 +5,17 @@ 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;
|
||||
|
||||
public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
||||
@MethodsReturnNonnullByDefault
|
||||
public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements IAirCurrentSource {
|
||||
|
||||
public AirCurrent airCurrent;
|
||||
protected int airCurrentUpdateCooldown;
|
||||
|
@ -88,15 +88,18 @@ 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getAirflowOriginSide() {
|
||||
return this.getBlockState()
|
||||
.get(EncasedFanBlock.FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getAirFlowDirection() {
|
||||
float speed = getSpeed();
|
||||
if (speed == 0)
|
||||
|
|
|
@ -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 getWorld();
|
||||
|
||||
BlockPos getPos();
|
||||
|
||||
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 isRemoved();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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,6 +43,7 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
|||
setAlphaF(.25f);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
@ -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()))
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -51,7 +46,16 @@ 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 +86,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 +133,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 +172,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 +239,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 +266,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 +299,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 +317,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 +325,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 +343,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 +458,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 +503,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 +529,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 +598,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 +617,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 +646,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 +671,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 +681,31 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AirCurrent getAirCurrent() {
|
||||
return airCurrent;
|
||||
}
|
||||
|
||||
@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 Direction getAirflowOriginSide() {
|
||||
return world != null && !(world.getTileEntity(pos.down()) instanceof IAirCurrentSource)
|
||||
&& getBlockState().get(ChuteBlock.FACING) == Direction.DOWN ? Direction.DOWN : Direction.UP;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue