Factory Block Breaker Hopper insertion added (issue #121). Test block stripped.

This commit is contained in:
stfwi 2020-10-02 11:16:43 +02:00
parent 1753624e2a
commit 5bf8e5795f
5 changed files with 30 additions and 203 deletions

View file

@ -5,4 +5,4 @@ version_minecraft=1.16.3
version_forge_minecraft=1.16.3-34.1.0
version_fml_mappings=20200723-1.16.1
version_jei=1.16.3:7.3.2.36
version_engineersdecor=1.1.2
version_engineersdecor=1.1.3-b1

View file

@ -11,6 +11,8 @@ Mod sources for Minecraft version 1.16.3.
## Version history
~ v1.1.3-b1 [A] The Factory Block Breaker can insert items into Hoppers underneath it (issue #121, winsrp).
- v1.1.2 [U] Updated to Forge 1.16.3-34.1.0.
[A] Added Factory Hopper insertion/extraction for entities like Minecarts (issue #125, ty boneskull).

View file

@ -11,6 +11,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Overlay;
import net.minecraft.world.World;
import net.minecraft.world.IBlockReader;
@ -284,14 +285,30 @@ public class EdBreaker
world.addEntity(e);
}
private static boolean canInsertInto(World world, BlockPos pos)
{
// Maybe make a tag for that. The question is if it is actually worth it, or if that would be only
// tag spamming the game. So for now only FH and VH.
final BlockState state = world.getBlockState(pos);
return (state.getBlock() == ModContent.FACTORY_HOPPER) || (state.getBlock() == Blocks.HOPPER);
}
private boolean breakBlock(BlockState state, BlockPos pos, World world)
{
if(world.isRemote || (!(world instanceof ServerWorld)) || world.restoringBlockSnapshots) return false; // retry next cycle
List<ItemStack> drops;
final Block block = state.getBlock();
final boolean insert = canInsertInto(world, getPos().down());
drops = Block.getDrops(state, (ServerWorld)world, pos, world.getTileEntity(pos));
world.removeBlock(pos, false);
for(ItemStack drop:drops) spawnBlockAsEntity(world, pos, drop);
for(ItemStack drop:drops) {
if(!insert) {
spawnBlockAsEntity(world, pos, drop);
} else {
final ItemStack remaining = Inventories.insert(world, getPos().down(), Direction.UP, drop, false);
if(!remaining.isEmpty()) spawnBlockAsEntity(world, pos, remaining);
}
}
SoundType stype = state.getBlock().getSoundType(state, world, pos, null);
if(stype != null) world.playSound(null, pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
return true;

View file

@ -19,26 +19,16 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.fluid.Fluids;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@ -99,20 +89,9 @@ public class EdTestBlock
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class TestTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider //, IItemHandler, IEnergyStorage
public static class TestTileEntity extends TileEntity implements ITickableTileEntity
{
private int tick_interval_ = 10;
private int passive_tank_capacity_ = 32000;
private FluidStack passive_tank_ = FluidStack.EMPTY;
private FluidStack passive_drain_fluidstack_ = new FluidStack(Fluids.WATER, 1000);
private int passive_drain_max_flowrate_ = 1000;
private int passive_fill_max_flowrate_ = 1000;
private int passive_num_drained_general_mb_ = 0;
private int passive_num_drained_specific_mb_ = 0;
private int passive_num_filled_specific_mb_ = 0;
private int passive_num_fh_interactions_ = 0;
private FluidStack active_fill_fluidstack_ = FluidStack.EMPTY;
private int active_num_filled_ = 0;
private int tick_timer_ = 0;
// ------------------------------------------------------------------------------------------
@ -125,199 +104,28 @@ public class EdTestBlock
// ------------------------------------------------------------------------------------------
private Direction block_facing()
{
BlockState st = getWorld().getBlockState(getPos());
return (st.getBlock() instanceof TestBlock) ? st.get(TestBlock.FACING) : Direction.NORTH;
}
private String dump_fluid_stack(FluidStack fs)
{
String s = "";
if(fs.getFluid().getRegistryName().getNamespace() != "minecraft") s += fs.getFluid().getRegistryName().getNamespace()+":";
s += fs.getFluid().getRegistryName().getPath();
s += " x" + fs.getAmount();
return "[" + s + "]";
}
public void activated(PlayerEntity player, Hand hand, BlockRayTraceResult hit)
{
if(world.isRemote()) return;
final ItemStack held_stack = player.getHeldItem(hand);
// Empty hand -> statistics
{
if(held_stack.isEmpty()) {
String message = "";
if(passive_num_filled_specific_mb_>0 || passive_num_drained_specific_mb_>0 || passive_num_drained_general_mb_>0) {
message += "Fluid handler: filled:" + passive_num_filled_specific_mb_ + ", drained:" + (passive_num_drained_specific_mb_+ passive_num_drained_general_mb_) + ", interactions:" + passive_num_fh_interactions_ + "\n";
}
if(active_num_filled_>0) {
message += "Fluid insertion:" + active_num_filled_ + "mb, (current:" + dump_fluid_stack(active_fill_fluidstack_) + ")\n";
}
if(message.isEmpty()) {
message = "No fluid, energy, or item interactions done yet.";
}
Auxiliaries.playerChatMessage(player, message);
return;
}
}
// Fluid container -> set fluid to insert, increase/decrease amount.
{
final IFluidHandlerItem fhi = held_stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY).orElse(null);
if((fhi != null)) {
int ntanks = fhi.getTanks();
if(ntanks == 0) return;
int capacity = fhi.getTankCapacity(0);
FluidStack fs = fhi.drain(capacity, FluidAction.SIMULATE);
if(!fs.isEmpty()) {
if(active_fill_fluidstack_.isEmpty()) {
active_fill_fluidstack_ = fs.copy();
Auxiliaries.playerChatMessage(player, "Fluid insertion fluid set: " + dump_fluid_stack(active_fill_fluidstack_));
} else if(fs.isFluidEqual(active_fill_fluidstack_)) {
active_fill_fluidstack_.grow(fs.getAmount());
Auxiliaries.playerChatMessage(player, "Fluid insertion flowrate increased: " + dump_fluid_stack(active_fill_fluidstack_));
} else {
int amount = active_fill_fluidstack_.getAmount();
active_fill_fluidstack_ = fs.copy();
active_fill_fluidstack_.setAmount(amount);
Auxiliaries.playerChatMessage(player, "Fluid insertion fluid changed: " + dump_fluid_stack(active_fill_fluidstack_));
}
} else {
if(!active_fill_fluidstack_.isEmpty()) {
active_fill_fluidstack_.shrink(1000);
if(active_fill_fluidstack_.isEmpty()) active_fill_fluidstack_ = FluidStack.EMPTY;
Auxiliaries.playerChatMessage(player, "Fluid insertion flowrate decreased: " + dump_fluid_stack(active_fill_fluidstack_));
} else {
Auxiliaries.playerChatMessage(player, "Fluid insertion disabled.");
}
}
passive_drain_fluidstack_ = active_fill_fluidstack_.copy(); // currently no difference
return;
}
}
}
{}
// TileEntity ------------------------------------------------------------------------------
@Override
public void read(BlockState state, CompoundNBT nbt)
{
super.read(state, nbt);
if(nbt.contains("passive_tank")) passive_tank_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("passive_tank"));
if(nbt.contains("passive_drain")) passive_drain_fluidstack_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("passive_drain"));
if(nbt.contains("active")) active_fill_fluidstack_ = FluidStack.loadFluidStackFromNBT(nbt.getCompound("active"));
}
{ super.read(state, nbt); }
@Override
public CompoundNBT write(CompoundNBT nbt)
{
super.write(nbt);
if(!passive_tank_.isEmpty()) nbt.put("passive_tank", passive_tank_.writeToNBT(new CompoundNBT()));
if(!passive_drain_fluidstack_.isEmpty()) nbt.put("passive_drain", passive_drain_fluidstack_.writeToNBT(new CompoundNBT()));
if(!active_fill_fluidstack_.isEmpty()) nbt.put("active", active_fill_fluidstack_.writeToNBT(new CompoundNBT()));
return nbt;
}
{ super.write(nbt); return nbt; }
@Override
public void remove()
{
super.remove();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new MainFluidHandler(this));
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
if(facing != block_facing()) return fluid_handler_.cast();
return LazyOptional.empty();
}
return super.getCapability(capability, facing);
}
// IFluidHandler ---------------------------------------------------------------------------
private static class MainFluidHandler implements IFluidHandler
{
private TestTileEntity te;
public MainFluidHandler(TestTileEntity te)
{ this.te = te; }
@Override public int getTanks()
{ return 1; }
@Override public FluidStack getFluidInTank(int tank)
{ return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank)
{ return te.passive_tank_capacity_; }
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
++te.passive_num_fh_interactions_;
if(resource.isEmpty()) return FluidStack.EMPTY;
if(!resource.isFluidEqual(te.passive_drain_fluidstack_)) return FluidStack.EMPTY;
FluidStack st = resource.copy();
st.setAmount(MathHelper.clamp(st.getAmount(), 0, te.passive_drain_max_flowrate_));
if(st.isEmpty()) return FluidStack.EMPTY;
if(action==FluidAction.EXECUTE) te.passive_num_drained_specific_mb_ += st.getAmount();
return st;
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
++te.passive_num_fh_interactions_;
maxDrain = MathHelper.clamp(maxDrain, 0, te.passive_drain_max_flowrate_);
if((te.passive_drain_fluidstack_.isEmpty()) || (maxDrain<=0)) return FluidStack.EMPTY;
if(action==FluidAction.EXECUTE) te.passive_num_drained_general_mb_ += maxDrain;
FluidStack st = te.passive_drain_fluidstack_.copy();
st.setAmount(maxDrain);
return st;
}
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack)
{ return true; }
@Override public int fill(FluidStack resource, FluidAction action)
{
++te.passive_num_fh_interactions_;
int amount = MathHelper.clamp(resource.getAmount(), 0, te.passive_fill_max_flowrate_);
if(action == FluidAction.EXECUTE) {
te.passive_num_filled_specific_mb_ += amount;
if(te.passive_tank_.isFluidEqual(resource)) {
int level = (int)MathHelper.clamp((long)te.passive_tank_.getAmount() + (long)amount, (long)0, (long)Integer.MAX_VALUE);
te.passive_tank_.setAmount(level);
}
}
return amount;
}
}
// ITickableTileEntity ----------------------------------------------------------------------
private void fluid_insertion()
{
if(active_fill_fluidstack_.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos.offset(block_facing()));
if(te == null) return;
final IFluidHandler fh = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, block_facing().getOpposite()).orElse(null);
if(fh == null) return;
int filled = fh.fill(active_fill_fluidstack_.copy(), FluidAction.EXECUTE);
active_num_filled_ += filled;
}
{ super.remove(); }
@Override
public void tick()
{
if(world.isRemote) return;
if(--tick_timer_ > 0) return;
tick_interval_ = MathHelper.clamp(tick_interval_ ,1 , 200);
if((world.isRemote) || (--tick_timer_ > 0)) return;
tick_timer_ = tick_interval_;
fluid_insertion();
}
}

View file

@ -62,11 +62,11 @@ public class Inventories
public static ItemStack insert(TileEntity te, @Nullable Direction side, ItemStack stack, boolean simulate)
{
if(te==null) return stack;
if(te == null) return stack;
IItemHandler hnd = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side).orElse(null);
if(hnd != null) {
if(hnd == null) {
hnd = (IItemHandler)te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
} else if((side!=null) && (te instanceof ISidedInventory)) {
} else if((side!=null) && (te instanceof ISidedInventory)) {
hnd = new SidedInvWrapper((ISidedInventory)te, side);
} else if(te instanceof IInventory) {
hnd = new InvWrapper((IInventory)te);