mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 20:11:35 +01:00
Merge & Port
This commit is contained in:
commit
5a176204a5
10 changed files with 376 additions and 246 deletions
|
@ -89,7 +89,7 @@ public class ChromaticCompoundItem extends Item {
|
|||
if (y < 0 && y - yMotion < -10 && config.enableShadowSteelRecipe.get()) {
|
||||
ItemStack newStack = AllItems.SHADOW_STEEL.asStack();
|
||||
newStack.setCount(stack.getCount());
|
||||
data.putBoolean("FromVoid", true);
|
||||
data.putBoolean("JustCreated", true);
|
||||
entity.setItem(newStack);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ public class ChromaticCompoundItem extends Item {
|
|||
ItemEntity newEntity = new ItemEntity(world, entity.getX(), entity.getY(), entity.getZ(), newStack);
|
||||
newEntity.setMotion(entity.getMotion());
|
||||
newEntity.getPersistentData()
|
||||
.putBoolean("FromLight", true);
|
||||
.putBoolean("JustCreated", true);
|
||||
itemData.remove("CollectingLight");
|
||||
world.addEntity(newEntity);
|
||||
|
||||
|
@ -119,10 +119,8 @@ public class ChromaticCompoundItem extends Item {
|
|||
int entityZ = MathHelper.floor(entity.getZ());
|
||||
int localWorldHeight = world.getHeight(Heightmap.Type.WORLD_SURFACE, entityX, entityZ);
|
||||
|
||||
BlockPos.Mutable testPos = new BlockPos.Mutable(
|
||||
entityX,
|
||||
Math.min(MathHelper.floor(entity.getY()), localWorldHeight),
|
||||
entityZ);
|
||||
BlockPos.Mutable testPos =
|
||||
new BlockPos.Mutable(entityX, Math.min(MathHelper.floor(entity.getY()), localWorldHeight), entityZ);
|
||||
|
||||
while (testPos.getY() > 0) {
|
||||
testPos.move(Direction.DOWN);
|
||||
|
@ -132,11 +130,13 @@ public class ChromaticCompoundItem extends Item {
|
|||
if (state.getBlock() == Blocks.BEACON) {
|
||||
TileEntity te = world.getTileEntity(testPos);
|
||||
|
||||
if (!(te instanceof BeaconTileEntity)) break;
|
||||
if (!(te instanceof BeaconTileEntity))
|
||||
break;
|
||||
|
||||
BeaconTileEntity bte = (BeaconTileEntity) te;
|
||||
|
||||
if (bte.getLevels() != 0 && !bte.beamSegments.isEmpty()) isOverBeacon = true;
|
||||
if (bte.getLevels() != 0 && !bte.beamSegments.isEmpty())
|
||||
isOverBeacon = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ public class ChromaticCompoundItem extends Item {
|
|||
if (isOverBeacon) {
|
||||
ItemStack newStack = AllItems.REFINED_RADIANCE.asStack();
|
||||
newStack.setCount(stack.getCount());
|
||||
data.putBoolean("FromLight", true);
|
||||
data.putBoolean("JustCreated", true);
|
||||
entity.setItem(newStack);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package com.simibubi.create.content.curiosities;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class NoGravMagicalDohickyItem extends Item {
|
||||
|
||||
public NoGravMagicalDohickyItem(Properties p_i48487_1_) {
|
||||
super(p_i48487_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
|
||||
World world = entity.world;
|
||||
Vector3d pos = entity.getPositionVec();
|
||||
CompoundNBT persistentData = entity.getPersistentData();
|
||||
|
||||
if (world.isRemote) {
|
||||
if (world.rand.nextFloat() < getIdleParticleChance(entity)) {
|
||||
Vector3d ppos = VecHelper.offsetRandomly(pos, world.rand, .5f);
|
||||
world.addParticle(ParticleTypes.END_ROD, ppos.x, pos.y, ppos.z, 0, -.1f, 0);
|
||||
}
|
||||
|
||||
if (entity.isSilent() && !persistentData.getBoolean("PlayEffects")) {
|
||||
Vector3d basemotion = new Vector3d(0, 1, 0);
|
||||
world.addParticle(ParticleTypes.FLASH, pos.x, pos.y, pos.z, 0, 0, 0);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vector3d motion = VecHelper.offsetRandomly(basemotion, world.rand, 1);
|
||||
world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
}
|
||||
persistentData.putBoolean("PlayEffects", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
entity.setNoGravity(true);
|
||||
|
||||
if (!persistentData.contains("JustCreated"))
|
||||
return false;
|
||||
onCreated(entity, persistentData);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected float getIdleParticleChance(ItemEntity entity) {
|
||||
return MathHelper.clamp(entity.getItem()
|
||||
.getCount() - 10, 5, 100) / 64f;
|
||||
}
|
||||
|
||||
protected void onCreated(ItemEntity entity, CompoundNBT persistentData) {
|
||||
entity.lifespan = 6000;
|
||||
persistentData.remove("JustCreated");
|
||||
|
||||
// just a flag to tell the client to play an effect
|
||||
entity.setSilent(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,10 @@
|
|||
package com.simibubi.create.content.curiosities;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
public class RefinedRadianceItem extends Item {
|
||||
public class RefinedRadianceItem extends NoGravMagicalDohickyItem {
|
||||
|
||||
public RefinedRadianceItem(Properties properties) {
|
||||
super(properties);
|
||||
|
@ -22,38 +16,10 @@ public class RefinedRadianceItem extends Item {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
|
||||
World world = entity.world;
|
||||
Vector3d pos = entity.getPositionVec();
|
||||
|
||||
if (world.isRemote && entity.hasNoGravity()) {
|
||||
if (world.rand.nextFloat() < MathHelper.clamp(entity.getItem().getCount() - 10, 1, 100) / 64f) {
|
||||
Vector3d ppos = VecHelper.offsetRandomly(pos, world.rand, .5f);
|
||||
world.addParticle(ParticleTypes.END_ROD, ppos.x, pos.y, ppos.z, 0, -.1f, 0);
|
||||
}
|
||||
|
||||
if (!entity.getPersistentData().contains("ClientAnimationPlayed")) {
|
||||
Vector3d basemotion = new Vector3d(0, 1, 0);
|
||||
world.addParticle(ParticleTypes.FLASH, pos.x, pos.y, pos.z, 0, 0, 0);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vector3d motion = VecHelper.offsetRandomly(basemotion, world.rand, 1);
|
||||
world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
}
|
||||
entity.getPersistentData().putBoolean("ClientAnimationPlayed", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entity.getPersistentData().contains("FromLight"))
|
||||
return false;
|
||||
|
||||
entity.lifespan = 6000;
|
||||
entity.setNoGravity(true);
|
||||
entity.setMotion(entity.getMotion().add(0, .15f, 0));
|
||||
entity.getPersistentData().remove("FromLight");
|
||||
return false;
|
||||
protected void onCreated(ItemEntity entity, CompoundNBT persistentData) {
|
||||
super.onCreated(entity, persistentData);
|
||||
entity.setMotion(entity.getMotion()
|
||||
.add(0, .15f, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,56 +1,26 @@
|
|||
package com.simibubi.create.content.curiosities;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ShadowSteelItem extends Item {
|
||||
public class ShadowSteelItem extends NoGravMagicalDohickyItem {
|
||||
|
||||
public ShadowSteelItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
|
||||
World world = entity.world;
|
||||
Vector3d pos = entity.getPositionVec();
|
||||
|
||||
if (world.isRemote && entity.hasNoGravity()) {
|
||||
if (world.rand.nextFloat() < MathHelper.clamp(entity.getItem().getCount() - 10,
|
||||
Math.min(entity.getMotion().y * 20, 20), 100) / 64f) {
|
||||
Vector3d ppos = VecHelper.offsetRandomly(pos, world.rand, .5f);
|
||||
world.addParticle(ParticleTypes.END_ROD, ppos.x, pos.y, ppos.z, 0, -.1f, 0);
|
||||
}
|
||||
|
||||
if (!entity.getPersistentData().contains("ClientAnimationPlayed")) {
|
||||
Vector3d basemotion = new Vector3d(0, 1, 0);
|
||||
world.addParticle(ParticleTypes.FLASH, pos.x, pos.y, pos.z, 0, 0, 0);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vector3d motion = VecHelper.offsetRandomly(basemotion, world.rand, 1);
|
||||
world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
|
||||
}
|
||||
entity.getPersistentData().putBoolean("ClientAnimationPlayed", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!entity.getPersistentData().contains("FromVoid"))
|
||||
return false;
|
||||
|
||||
entity.setNoGravity(true);
|
||||
protected void onCreated(ItemEntity entity, CompoundNBT persistentData) {
|
||||
super.onCreated(entity, persistentData);
|
||||
float yMotion = (entity.fallDistance + 3) / 50f;
|
||||
entity.setMotion(0, yMotion, 0);
|
||||
entity.lifespan = 6000;
|
||||
entity.getPersistentData().remove("FromVoid");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getIdleParticleChance(ItemEntity entity) {
|
||||
return (float) (MathHelper.clamp(entity.getItem()
|
||||
.getCount() - 10, MathHelper.clamp(entity.getMotion().y * 20, 5, 20), 100) / 64f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -188,12 +191,17 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
}
|
||||
|
||||
private static Random rand = new Random();
|
||||
private static Map<Pair<BrassTunnelTileEntity, Direction>, ItemStack> distributed = new IdentityHashMap<>();
|
||||
private static Set<Pair<BrassTunnelTileEntity, Direction>> full = new HashSet<>();
|
||||
|
||||
private void distribute(List<Pair<BrassTunnelTileEntity, Direction>> validTargets) {
|
||||
int amountTargets = validTargets.size();
|
||||
if (amountTargets == 0)
|
||||
return;
|
||||
|
||||
distributed.clear();
|
||||
full.clear();
|
||||
|
||||
int indexStart = previousOutputIndex % amountTargets;
|
||||
SelectionMode mode = selectionMode.get();
|
||||
boolean force = mode == SelectionMode.FORCED_ROUND_ROBIN || mode == SelectionMode.FORCED_SPLIT;
|
||||
|
@ -204,22 +212,24 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
if (mode == SelectionMode.PREFER_NEAREST || mode == SelectionMode.SYNCHRONIZE)
|
||||
indexStart = 0;
|
||||
|
||||
ItemStack toDistribute = null;
|
||||
int leftovers = 0;
|
||||
ItemStack toDistribute = stackToDistribute.copy();
|
||||
for (boolean distributeAgain : Iterate.trueAndFalse) {
|
||||
ItemStack toDistributeThisCycle = null;
|
||||
int remainingOutputs = amountTargets;
|
||||
int leftovers = 0;
|
||||
|
||||
for (boolean simulate : Iterate.trueAndFalse) {
|
||||
if (remainingOutputs == 0)
|
||||
return;
|
||||
break;
|
||||
|
||||
leftovers = 0;
|
||||
int index = indexStart;
|
||||
int stackSize = stackToDistribute.getCount();
|
||||
int stackSize = toDistribute.getCount();
|
||||
int splitStackSize = stackSize / remainingOutputs;
|
||||
int splitRemainder = stackSize % remainingOutputs;
|
||||
int visited = 0;
|
||||
|
||||
toDistribute = stackToDistribute.copy();
|
||||
toDistributeThisCycle = toDistribute.copy();
|
||||
if (!(force || split) && simulate)
|
||||
continue;
|
||||
|
||||
|
@ -230,21 +240,44 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
index = (index + 1) % amountTargets;
|
||||
visited++;
|
||||
|
||||
int count = split ? splitStackSize + (splitRemainder > 0 ? 1 : 0) : stackSize;
|
||||
ItemStack toOutput = ItemHandlerHelper.copyStackWithSize(toDistribute, count);
|
||||
ItemStack remainder = insertIntoTunnel(tunnel, side, toOutput, simulate);
|
||||
|
||||
if (remainder == null || remainder.getCount() == count) {
|
||||
if (force)
|
||||
return;
|
||||
if (full.contains(pair)) {
|
||||
if (split && simulate)
|
||||
remainingOutputs--;
|
||||
continue;
|
||||
}
|
||||
|
||||
int count = split ? splitStackSize + (splitRemainder > 0 ? 1 : 0) : stackSize;
|
||||
ItemStack toOutput = ItemHandlerHelper.copyStackWithSize(toDistributeThisCycle, count);
|
||||
|
||||
// Grow by 1 to determine if target is full even after a successful transfer
|
||||
boolean testWithIncreasedCount = distributed.containsKey(pair);
|
||||
int increasedCount = testWithIncreasedCount ? distributed.get(pair)
|
||||
.getCount() : 0;
|
||||
if (testWithIncreasedCount)
|
||||
toOutput.grow(increasedCount);
|
||||
|
||||
ItemStack remainder = insertIntoTunnel(tunnel, side, toOutput, true);
|
||||
|
||||
if (remainder == null || remainder.getCount() == (testWithIncreasedCount ? count + 1 : count)) {
|
||||
if (force)
|
||||
return;
|
||||
if (split && simulate)
|
||||
remainingOutputs--;
|
||||
if (!simulate)
|
||||
full.add(pair);
|
||||
continue;
|
||||
} else if (!remainder.isEmpty() && !simulate) {
|
||||
full.add(pair);
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
toOutput.shrink(remainder.getCount());
|
||||
distributed.put(pair, toOutput);
|
||||
}
|
||||
|
||||
leftovers += remainder.getCount();
|
||||
toDistribute.shrink(count);
|
||||
if (toDistribute.isEmpty())
|
||||
toDistributeThisCycle.shrink(count);
|
||||
if (toDistributeThisCycle.isEmpty())
|
||||
break;
|
||||
splitRemainder--;
|
||||
if (!split)
|
||||
|
@ -252,7 +285,21 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
}
|
||||
}
|
||||
|
||||
stackToDistribute = ItemHandlerHelper.copyStackWithSize(stackToDistribute, toDistribute.getCount() + leftovers);
|
||||
toDistribute.setCount(toDistributeThisCycle.getCount() + leftovers);
|
||||
if (leftovers == 0 && distributeAgain)
|
||||
break;
|
||||
if (!split)
|
||||
break;
|
||||
}
|
||||
|
||||
int failedTransferrals = 0;
|
||||
for (Entry<Pair<BrassTunnelTileEntity, Direction>, ItemStack> entry : distributed.entrySet()) {
|
||||
Pair<BrassTunnelTileEntity, Direction> pair = entry.getKey();
|
||||
failedTransferrals += insertIntoTunnel(pair.getKey(), pair.getValue(), entry.getValue(), false).getCount();
|
||||
}
|
||||
|
||||
toDistribute.grow(failedTransferrals);
|
||||
stackToDistribute = ItemHandlerHelper.copyStackWithSize(stackToDistribute, toDistribute.getCount());
|
||||
previousOutputIndex++;
|
||||
previousOutputIndex %= amountTargets;
|
||||
notifyUpdate();
|
||||
|
@ -418,9 +465,16 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
if (!AllBlocks.BRASS_TUNNEL.has(blockState))
|
||||
return;
|
||||
|
||||
boolean prioritizeSides = tunnelTE == this;
|
||||
|
||||
for (boolean sidePass : Iterate.trueAndFalse) {
|
||||
if (!prioritizeSides && sidePass)
|
||||
continue;
|
||||
for (Direction direction : Iterate.horizontalDirections) {
|
||||
if (direction == movementFacing && below.getSpeed() == 0)
|
||||
continue;
|
||||
if (prioritizeSides && sidePass == (direction.getAxis() == movementFacing.getAxis()))
|
||||
continue;
|
||||
if (direction == movementFacing.getOpposite())
|
||||
continue;
|
||||
if (tunnelTE.sides.contains(direction)) {
|
||||
|
@ -430,7 +484,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
TileEntityBehaviour.get(world, offset, DirectBeltInputBehaviour.TYPE);
|
||||
if (inputBehaviour == null) {
|
||||
if (direction == movementFacing)
|
||||
if (!BlockHelper.hasBlockSolidSide(world.getBlockState(offset), world, offset, direction.getOpposite()))
|
||||
if (!BlockHelper.hasBlockSolidSide(world.getBlockState(offset), world, offset,
|
||||
direction.getOpposite()))
|
||||
validOutputs.add(Pair.of(tunnelTE, direction));
|
||||
continue;
|
||||
}
|
||||
|
@ -440,6 +495,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehavioursDeferred(List<TileEntityBehaviour> behaviours) {
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
package com.simibubi.create.content.logistics.block.chute;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.fan.AirCurrent;
|
||||
|
@ -207,7 +214,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
beltBelowOffset = i - 1;
|
||||
break;
|
||||
}
|
||||
this.bottomPullDistance = flowLimit;
|
||||
this.bottomPullDistance = Math.max(0, flowLimit);
|
||||
}
|
||||
sendData();
|
||||
}
|
||||
|
@ -322,29 +329,40 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
private void handleInputFromAbove() {
|
||||
if (!capAbove.isPresent())
|
||||
capAbove = grabCapability(Direction.UP);
|
||||
if (capAbove.isPresent()) {
|
||||
if (!capAbove.isPresent())
|
||||
return;
|
||||
|
||||
int count = getExtractionAmount();
|
||||
if (count == 0)
|
||||
item =
|
||||
ItemHelper.extract(capAbove.orElse(null), this::canAcceptItem, ExtractionCountMode.UPTO, 16, false);
|
||||
else
|
||||
item = ItemHelper.extract(capAbove.orElse(null), this::canAcceptItem, ExtractionCountMode.EXACTLY,
|
||||
count, false);
|
||||
IItemHandler inv = capAbove.orElse(null);
|
||||
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
||||
if (count == 0) {
|
||||
item = ItemHelper.extract(inv, canAccept, ExtractionCountMode.UPTO, 16, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ItemHelper.extract(inv, canAccept, ExtractionCountMode.EXACTLY, count, true)
|
||||
.isEmpty())
|
||||
item = ItemHelper.extract(inv, canAccept, ExtractionCountMode.EXACTLY, count, false);
|
||||
}
|
||||
|
||||
private void handleInputFromBelow() {
|
||||
if (!capBelow.isPresent())
|
||||
capBelow = grabCapability(Direction.DOWN);
|
||||
if (capBelow.isPresent()) {
|
||||
if (!capBelow.isPresent())
|
||||
return;
|
||||
|
||||
int count = getExtractionAmount();
|
||||
if (count == 0)
|
||||
item =
|
||||
ItemHelper.extract(capBelow.orElse(null), this::canAcceptItem, ExtractionCountMode.UPTO, 16, false);
|
||||
else
|
||||
item = ItemHelper.extract(capBelow.orElse(null), this::canAcceptItem, ExtractionCountMode.EXACTLY,
|
||||
count, false);
|
||||
IItemHandler inv = capBelow.orElse(null);
|
||||
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
||||
|
||||
if (count == 0) {
|
||||
item = ItemHelper.extract(inv, canAccept, ExtractionCountMode.UPTO, 16, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ItemHelper.extract(inv, canAccept, ExtractionCountMode.EXACTLY, count, true)
|
||||
.isEmpty())
|
||||
item = ItemHelper.extract(inv, canAccept, ExtractionCountMode.EXACTLY, count, false);
|
||||
}
|
||||
|
||||
private boolean handleDownwardOutput(boolean simulate) {
|
||||
|
@ -358,9 +376,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
capBelow = grabCapability(Direction.DOWN);
|
||||
if (capBelow.isPresent()) {
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
|
||||
ItemStack held = getItem();
|
||||
if (!simulate)
|
||||
setItem(remainder);
|
||||
if (remainder.isEmpty())
|
||||
if (remainder.getCount() != held.getCount())
|
||||
return true;
|
||||
if (direction == Direction.DOWN)
|
||||
return false;
|
||||
|
@ -408,10 +427,11 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
if (!capAbove.isPresent())
|
||||
capAbove = grabCapability(Direction.UP);
|
||||
if (capAbove.isPresent()) {
|
||||
int countBefore = item.getCount();
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
|
||||
if (!simulate)
|
||||
setItem(ItemStack.EMPTY);
|
||||
return remainder.isEmpty();
|
||||
item = remainder;
|
||||
return countBefore != remainder.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.foundation.block.ITE;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
|
@ -49,10 +50,16 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
|
|||
.orElse(super.getSlipperiness(state, world, pos, entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World world, BlockPos pos, Block p_220069_4_,
|
||||
BlockPos p_220069_5_, boolean p_220069_6_) {
|
||||
withTileEntityDo(world, pos, EjectorTileEntity::updateSignal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFallenUpon(World p_180658_1_, BlockPos p_180658_2_, Entity p_180658_3_, float p_180658_4_) {
|
||||
Optional<EjectorTileEntity> tileEntityOptional = getTileEntityOptional(p_180658_1_, p_180658_2_);
|
||||
if (tileEntityOptional.isPresent()) {
|
||||
if (tileEntityOptional.isPresent() && !p_180658_3_.bypassesLandingEffects()) {
|
||||
p_180658_3_.handleFallDamage(p_180658_4_, 0.0F);
|
||||
return;
|
||||
}
|
||||
|
@ -67,6 +74,8 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
|
|||
return;
|
||||
if (!entityIn.isAlive())
|
||||
return;
|
||||
if (entityIn.bypassesLandingEffects())
|
||||
return;
|
||||
if (entityIn instanceof ItemEntity) {
|
||||
SharedDepotBlockMethods.onLanded(worldIn, entityIn);
|
||||
return;
|
||||
|
@ -79,6 +88,8 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
|
|||
EjectorTileEntity ejectorTileEntity = teProvider.get();
|
||||
if (ejectorTileEntity.getState() == State.RETRACTING)
|
||||
return;
|
||||
if (ejectorTileEntity.powered)
|
||||
return;
|
||||
if (ejectorTileEntity.launcher.getHorizontalDistance() == 0)
|
||||
return;
|
||||
|
||||
|
@ -97,7 +108,7 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
|
|||
}
|
||||
}
|
||||
|
||||
ejectorTileEntity.launchAll();
|
||||
ejectorTileEntity.activate();
|
||||
ejectorTileEntity.notifyUpdate();
|
||||
if (entityIn.world.isRemote)
|
||||
AllPackets.channel.sendToServer(new EjectorTriggerPacket(ejectorTileEntity.getPos()));
|
||||
|
|
|
@ -58,6 +58,8 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
DepotBehaviour depotBehaviour;
|
||||
EntityLauncher launcher;
|
||||
LerpedFloat lidProgress;
|
||||
boolean powered;
|
||||
boolean launch;
|
||||
State state;
|
||||
|
||||
public enum State {
|
||||
|
@ -71,6 +73,7 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
.startWithValue(1);
|
||||
state = State.RETRACTING;
|
||||
launchedItems = new ArrayList<>();
|
||||
powered = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,10 +95,24 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
depotBehaviour.addSubBehaviours(behaviours);
|
||||
}
|
||||
|
||||
public void launchAll() {
|
||||
if (state != State.CHARGED && !(world.isRemote && state == State.LAUNCHING))
|
||||
return;
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
updateSignal();
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
launch = true;
|
||||
nudgeEntities();
|
||||
}
|
||||
|
||||
protected boolean cannotLaunch() {
|
||||
return state != State.CHARGED && !(world.isRemote && state == State.LAUNCHING);
|
||||
}
|
||||
|
||||
public void activateDeferred() {
|
||||
if (cannotLaunch())
|
||||
return;
|
||||
Direction facing = getFacing();
|
||||
List<Entity> entities =
|
||||
world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos).grow(-1 / 16f, 0, -1 / 16f));
|
||||
|
@ -135,12 +152,11 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
AllPackets.channel.sendToServer(new EjectorElytraPacket(pos));
|
||||
}
|
||||
|
||||
if (!world.isRemote) {
|
||||
lidProgress.chase(1, .8f, Chaser.EXP);
|
||||
state = State.LAUNCHING;
|
||||
|
||||
if (!world.isRemote) {
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE, SoundCategory.BLOCKS, .5f, 1f);
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, .125f, 1.4f);
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE, SoundCategory.BLOCKS, .35f, 1f);
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, .1f, 1.4f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +203,9 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!world.isRemote)
|
||||
world.markAndNotifyBlock(pos, world.getChunkAt(pos), getBlockState(), getBlockState(), 0, 512);
|
||||
|
||||
if (depotBehaviour.heldItem != null) {
|
||||
launchedItems.add(IntAttached.withZero(heldItemStack));
|
||||
depotBehaviour.removeHeldItem();
|
||||
|
@ -218,9 +237,13 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
|
||||
boolean doLogic = !world.isRemote || isVirtual();
|
||||
State prevState = state;
|
||||
|
||||
float maxTime = Math.max(3, (float) launcher.getTotalFlyingTicks());
|
||||
|
||||
if (launch) {
|
||||
launch = false;
|
||||
activateDeferred();
|
||||
}
|
||||
|
||||
for (Iterator<IntAttached<ItemStack>> iterator = launchedItems.iterator(); iterator.hasNext();) {
|
||||
IntAttached<ItemStack> intAttached = iterator.next();
|
||||
if (intAttached.exceeds((int) maxTime)) {
|
||||
|
@ -241,11 +264,19 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
|
||||
if (state == State.CHARGED) {
|
||||
lidProgress.setValue(0);
|
||||
lidProgress.updateChaseSpeed(0);
|
||||
if (doLogic)
|
||||
ejectIfTriggered();
|
||||
}
|
||||
|
||||
if (state == State.RETRACTING) {
|
||||
lidProgress.updateChaseSpeed(0);
|
||||
if (lidProgress.getValue() == 0 && doLogic) {
|
||||
state = State.CHARGED;
|
||||
lidProgress.setValue(0);
|
||||
sendData();
|
||||
}
|
||||
|
||||
float value = MathHelper.clamp(lidProgress.getValue() - getWindUpSpeed(), 0, 1);
|
||||
lidProgress.setValue(value);
|
||||
|
||||
|
@ -255,24 +286,22 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
if (((int) world.getGameTime()) % soundRate == 0 && doLogic)
|
||||
world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, volume,
|
||||
pitch);
|
||||
|
||||
if (lidProgress.getValue() == 0 && doLogic) {
|
||||
state = State.CHARGED;
|
||||
lidProgress.setValue(0);
|
||||
|
||||
List<Entity> entities =
|
||||
world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos).grow(-1 / 16f, 0, -1 / 16f));
|
||||
for (Entity entity : entities)
|
||||
if (!(entity instanceof PlayerEntity))
|
||||
entity.setPosition(entity.getX(), entity.getY() + volume, entity.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
if (state != prevState)
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
protected void nudgeEntities() {
|
||||
for (Entity entity : world.getEntitiesWithinAABB(Entity.class,
|
||||
new AxisAlignedBB(pos).grow(-1 / 16f, 0, -1 / 16f)))
|
||||
if (!(entity instanceof PlayerEntity))
|
||||
entity.setPosition(entity.getX(), entity.getY() + .125f, entity.getZ());
|
||||
}
|
||||
|
||||
protected void ejectIfTriggered() {
|
||||
if (powered)
|
||||
return;
|
||||
int presentStackSize = depotBehaviour.getPresentStackSize();
|
||||
if (presentStackSize == 0)
|
||||
return;
|
||||
|
@ -280,11 +309,11 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
return;
|
||||
|
||||
Direction funnelFacing = getFacing().getOpposite();
|
||||
ItemStack held = depotBehaviour.getHeldItemStack();
|
||||
if (AbstractFunnelBlock.getFunnelFacing(world.getBlockState(pos.up())) == funnelFacing) {
|
||||
DirectBeltInputBehaviour directOutput = getBehaviour(DirectBeltInputBehaviour.TYPE);
|
||||
if (depotBehaviour.heldItem != null) {
|
||||
ItemStack tryFunnel =
|
||||
directOutput.tryExportingToBeltFunnel(depotBehaviour.getHeldItemStack(), funnelFacing, true);
|
||||
ItemStack tryFunnel = directOutput.tryExportingToBeltFunnel(held, funnelFacing, true);
|
||||
if (tryFunnel == null || !tryFunnel.isEmpty())
|
||||
return;
|
||||
}
|
||||
|
@ -294,11 +323,11 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
|
||||
// Do not eject if target cannot accept held item
|
||||
if (targetOpenInv != null && depotBehaviour.heldItem != null
|
||||
&& targetOpenInv.handleInsertion(depotBehaviour.getHeldItemStack(), Direction.UP, true)
|
||||
.isItemEqual(depotBehaviour.getHeldItemStack()))
|
||||
&& targetOpenInv.handleInsertion(held, Direction.UP, true)
|
||||
.getCount() == held.getCount())
|
||||
return;
|
||||
|
||||
launchAll();
|
||||
activate();
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
|
@ -368,6 +397,7 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
super.write(compound, clientPacket);
|
||||
compound.putInt("HorizontalDistance", launcher.getHorizontalDistance());
|
||||
compound.putInt("VerticalDistance", launcher.getVerticalDistance());
|
||||
compound.putBoolean("Powered", powered);
|
||||
NBTHelper.writeEnum(compound, "State", state);
|
||||
compound.put("Lid", lidProgress.writeNBT());
|
||||
compound.put("LaunchedItems",
|
||||
|
@ -386,12 +416,21 @@ public class EjectorTileEntity extends KineticTileEntity {
|
|||
launcher.clamp(AllConfigs.SERVER.kinetics.maxEjectorDistance.get());
|
||||
}
|
||||
|
||||
powered = compound.getBoolean("Powered");
|
||||
state = NBTHelper.readEnum(compound, "State", State.class);
|
||||
lidProgress.readNBT(compound.getCompound("Lid"), clientPacket);
|
||||
launchedItems = NBTHelper.readCompoundList(compound.getList("LaunchedItems", NBT.TAG_COMPOUND),
|
||||
nbt -> IntAttached.read(nbt, ItemStack::read));
|
||||
}
|
||||
|
||||
public void updateSignal() {
|
||||
boolean shoudPower = world.isBlockPowered(pos);
|
||||
if (shoudPower == powered)
|
||||
return;
|
||||
powered = shoudPower;
|
||||
sendData();
|
||||
}
|
||||
|
||||
public void setTarget(int horizontalDistance, int verticalDistance) {
|
||||
launcher.set(Math.max(1, horizontalDistance), verticalDistance);
|
||||
if (horizontalDistance == 0 && verticalDistance == 0) {
|
||||
|
|
|
@ -23,7 +23,7 @@ public class EjectorTriggerPacket extends TileEntityConfigurationPacket<EjectorT
|
|||
|
||||
@Override
|
||||
protected void applySettings(EjectorTileEntity te) {
|
||||
te.launchAll();
|
||||
te.activate();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
.stream()
|
||||
.filter(rl -> tag.getMainItem()
|
||||
.isEmpty()
|
||||
|| tag.getMainItem()
|
||||
|| !tag.getMainItem()
|
||||
.getItem()
|
||||
.getRegistryName()
|
||||
.equals(rl))
|
||||
|
|
Loading…
Reference in a new issue