diff --git a/src/main/java/api/hbm/fluidmk2/IFluidBufferTransceiverMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidBufferTransceiverMK2.java new file mode 100644 index 000000000..7d0ba5d53 --- /dev/null +++ b/src/main/java/api/hbm/fluidmk2/IFluidBufferTransceiverMK2.java @@ -0,0 +1,5 @@ +package api.hbm.fluidmk2; + +public interface IFluidBufferTransceiverMK2 extends IFluidStandardTransceiverMK2 { + +} diff --git a/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java index 2a1a3ce43..5cbbf4e58 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java @@ -24,29 +24,29 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 { public default void tryProvide(FluidTank tank, World world, DirPos pos) { tryProvide(tank.getTankType(), tank.getPressure(), world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); } public default void tryProvide(FluidType type, World world, DirPos pos) { tryProvide(type, 0, world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); } public default void tryProvide(FluidType type, int pressure, World world, DirPos pos) { tryProvide(type, pressure, world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); } - + public default void tryProvide(FluidTank tank, World world, int x, int y, int z, ForgeDirection dir) { tryProvide(tank.getTankType(), tank.getPressure(), world, x, y, z, dir); } public default void tryProvide(FluidType type, World world, int x, int y, int z, ForgeDirection dir) { tryProvide(type, 0, world, x, y, z, dir); } - + public default void tryProvide(FluidType type, int pressure, World world, int x, int y, int z, ForgeDirection dir) { TileEntity te = Compat.getTileStandard(world, x, y, z); boolean red = false; - + if(te instanceof IFluidConnectorMK2) { IFluidConnectorMK2 con = (IFluidConnectorMK2) te; if(con.canConnect(type, dir.getOpposite())) { - + GenNode node = UniNodespace.getNode(world, x, y, z, type.getNetworkProvider()); - + if(node != null && node.net != null) { node.net.addProvider(this); red = true; } } } - - if(te instanceof IFluidReceiverMK2 && te != this) { + + if(te != this && te instanceof IFluidReceiverMK2 && !(te instanceof IFluidBufferTransceiverMK2)) { IFluidReceiverMK2 rec = (IFluidReceiverMK2) te; if(rec.canConnect(type, dir.getOpposite())) { long provides = Math.min(this.getFluidAvailable(type, pressure), this.getProviderSpeed(type, pressure)); @@ -56,7 +56,7 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 { this.useUpFluid(type, pressure, toTransfer); } } - + if(particleDebug) { NBTTagCompound data = new NBTTagCompound(); data.setString("type", "network"); @@ -71,9 +71,9 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 { PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, posX, posY, posZ), new TargetPoint(world.provider.dimensionId, posX, posY, posZ, 25)); } } - + public FluidTank[] getSendingTanks(); - + @Override public default long getFluidAvailable(FluidType type, int pressure) { long amount = 0; @@ -112,14 +112,14 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 { public default int[] getProvidingPressureRange(FluidType type) { int lowest = HIGHEST_VALID_PRESSURE; int highest = 0; - + for(FluidTank tank : getSendingTanks()) { if(tank.getTankType() == type) { if(tank.getPressure() < lowest) lowest = tank.getPressure(); if(tank.getPressure() > highest) highest = tank.getPressure(); } } - + return lowest <= highest ? new int[] {lowest, highest} : DEFAULT_PRESSURE_RANGE; } diff --git a/src/main/java/com/hbm/tileentity/machine/storage/TileEntityBarrel.java b/src/main/java/com/hbm/tileentity/machine/storage/TileEntityBarrel.java index 84db4a9ae..101843c50 100644 --- a/src/main/java/com/hbm/tileentity/machine/storage/TileEntityBarrel.java +++ b/src/main/java/com/hbm/tileentity/machine/storage/TileEntityBarrel.java @@ -1,7 +1,10 @@ package com.hbm.tileentity.machine.storage; import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; -import api.hbm.fluidmk2.IFluidStandardTransceiverMK2; +import api.hbm.fluidmk2.FluidNode; +import api.hbm.fluidmk2.IFluidBufferTransceiverMK2; + +import java.util.HashSet; import com.hbm.blocks.ModBlocks; import com.hbm.handler.CompatHandler; @@ -20,6 +23,8 @@ import com.hbm.tileentity.IFluidCopiable; import com.hbm.tileentity.IGUIProvider; import com.hbm.tileentity.IPersistentNBT; import com.hbm.tileentity.TileEntityMachineBase; +import com.hbm.uninos.UniNodespace; +import com.hbm.util.fauxpointtwelve.BlockPos; import com.hbm.util.fauxpointtwelve.DirPos; import cpw.mods.fml.common.Optional; import cpw.mods.fml.relauncher.Side; @@ -37,9 +42,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MathHelper; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")}) -public class TileEntityBarrel extends TileEntityMachineBase implements SimpleComponent, IFluidStandardTransceiverMK2, IPersistentNBT, IGUIProvider, CompatHandler.OCComponent, IFluidCopiable { +public class TileEntityBarrel extends TileEntityMachineBase implements SimpleComponent, IFluidBufferTransceiverMK2, IPersistentNBT, IGUIProvider, CompatHandler.OCComponent, IFluidCopiable { + + protected FluidNode node; + protected FluidType lastType; public FluidTank tank; public short mode = 0; @@ -90,10 +99,28 @@ public class TileEntityBarrel extends TileEntityMachineBase implements SimpleCom tank.setType(0, 1, slots); tank.loadTank(2, 3, slots); tank.unloadTank(4, 5, slots); - - for(DirPos pos : getConPos()) { - if(mode == 0 || mode == 1) this.trySubscribe(tank.getTankType(), worldObj, pos); - if(mode == 1 || mode == 2) this.tryProvide(tank, worldObj, pos); + + if(this.node == null || this.node.expired || tank.getTankType() != lastType) { + + this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); + + if(this.node == null || this.node.expired || tank.getTankType() != lastType) { + this.node = this.createNode(tank.getTankType()); + UniNodespace.createNode(worldObj, this.node); + lastType = tank.getTankType(); + } + } + + if(mode == 2 || mode == 1) { + this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN); + } else { + if(node != null && node.hasValidNet()) node.net.removeProvider(this); + } + + if(mode == 0 || mode == 1) { + if(node != null && node.hasValidNet()) node.net.addReceiver(this); + } else { + if(node != null && node.hasValidNet()) node.net.removeReceiver(this); } if(tank.getFill() > 0) { @@ -104,6 +131,30 @@ public class TileEntityBarrel extends TileEntityMachineBase implements SimpleCom } } + protected FluidNode createNode(FluidType type) { + DirPos[] conPos = getConPos(); + + HashSet posSet = new HashSet<>(); + posSet.add(new BlockPos(this)); + for(DirPos pos : conPos) { + ForgeDirection dir = pos.getDir(); + posSet.add(new BlockPos(pos.getX() - dir.offsetX, pos.getY() - dir.offsetY, pos.getZ() - dir.offsetZ)); + } + + return new FluidNode(type.getNetworkProvider(), posSet.toArray(new BlockPos[posSet.size()])).setConnections(conPos); + } + + @Override + public void invalidate() { + super.invalidate(); + + if(!worldObj.isRemote) { + if(this.node != null) { + UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); + } + } + } + @Override public void serialize(ByteBuf buf) { super.serialize(buf); @@ -220,6 +271,8 @@ public class TileEntityBarrel extends TileEntityMachineBase implements SimpleCom tank.writeToNBT(nbt, "tank"); } + @Override public boolean canConnect(FluidType fluid, ForgeDirection dir) { return true; } + @Override public FluidTank[] getSendingTanks() { return (mode == 1 || mode == 2) ? new FluidTank[] {tank} : new FluidTank[0]; diff --git a/src/main/java/com/hbm/tileentity/machine/storage/TileEntityMachineFluidTank.java b/src/main/java/com/hbm/tileentity/machine/storage/TileEntityMachineFluidTank.java index af722a0d5..a4272cfc1 100644 --- a/src/main/java/com/hbm/tileentity/machine/storage/TileEntityMachineFluidTank.java +++ b/src/main/java/com/hbm/tileentity/machine/storage/TileEntityMachineFluidTank.java @@ -1,7 +1,9 @@ package com.hbm.tileentity.machine.storage; import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; -import api.hbm.fluid.IFluidStandardTransceiver; +import api.hbm.fluidmk2.FluidNode; +import api.hbm.fluidmk2.IFluidBufferTransceiverMK2; + import com.hbm.blocks.BlockDummyable; import com.hbm.blocks.ModBlocks; import com.hbm.explosion.vanillant.ExplosionVNT; @@ -22,8 +24,10 @@ import com.hbm.inventory.fluid.tank.FluidTank; import com.hbm.lib.Library; import com.hbm.packet.PacketDispatcher; import com.hbm.tileentity.*; +import com.hbm.uninos.UniNodespace; import com.hbm.packet.toclient.AuxParticlePacketNT; import com.hbm.util.ParticleUtil; +import com.hbm.util.fauxpointtwelve.BlockPos; import com.hbm.util.fauxpointtwelve.DirPos; import cpw.mods.fml.common.Optional; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -45,23 +49,26 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Random; @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")}) -public class TileEntityMachineFluidTank extends TileEntityMachineBase implements SimpleComponent, OCComponent, IFluidStandardTransceiver, IPersistentNBT, IOverpressurable, IGUIProvider, IRepairable, IFluidCopiable { - +public class TileEntityMachineFluidTank extends TileEntityMachineBase implements SimpleComponent, OCComponent, IFluidBufferTransceiverMK2, IPersistentNBT, IOverpressurable, IGUIProvider, IRepairable, IFluidCopiable { + + protected FluidNode node; + protected FluidType lastType; + public FluidTank tank; public short mode = 0; public static final short modes = 4; public boolean hasExploded = false; - protected boolean sendingBrake = false; public boolean onFire = false; public byte lastRedstone = 0; public Explosion lastExplosion = null; - + public int age = 0; - + public TileEntityMachineFluidTank() { super(6); tank = new FluidTank(Fluids.NONE, 256000); @@ -82,7 +89,7 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements public void updateEntity() { if(!worldObj.isRemote) { - + //meta below 12 means that it's an old multiblock configuration if(this.getBlockMetadata() < 12) { //get old direction @@ -98,24 +105,43 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements worldObj.getTileEntity(xCoord, yCoord, zCoord).readFromNBT(data); return; } - + if(!hasExploded) { age++; - + if(age >= 20) { age = 0; this.markChanged(); } - - for(DirPos pos : getConPos()) { - if(mode == 0 || mode == 1) this.trySubscribe(tank.getTankType(), worldObj, pos); - if(mode == 1 || mode == 2) this.tryProvide(tank, worldObj, pos); + + if(this.node == null || this.node.expired || tank.getTankType() != lastType) { + + this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); + + if(this.node == null || this.node.expired || tank.getTankType() != lastType) { + this.node = this.createNode(tank.getTankType()); + UniNodespace.createNode(worldObj, this.node); + lastType = tank.getTankType(); + } } - + + if(mode == 2 || mode == 1) { + this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN); + } else { + if(node != null && node.hasValidNet()) node.net.removeProvider(this); + } + + if(mode == 0 || mode == 1) { + if(node != null && node.hasValidNet()) node.net.addReceiver(this); + } else { + if(node != null && node.hasValidNet()) node.net.removeReceiver(this); + } + tank.loadTank(2, 3, slots); tank.setType(0, 1, slots); - } else { - for(DirPos pos : getConPos()) this.tryUnsubscribe(tank.getTankType(), worldObj, pos.getX(), pos.getY(), pos.getZ()); + } else if(this.node != null) { + UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); + this.node = null; } byte comp = this.getComparatorPower(); //comparator shit @@ -131,11 +157,11 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements this.explode(); this.tank.setFill(0); } - + if(tank.getTankType().hasTrait(FT_Corrosive.class) && tank.getTankType().getTrait(FT_Corrosive.class).isHighlyCorrosive()) { this.explode(); } - + if(this.hasExploded) { int leaking = 0; @@ -146,26 +172,50 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements } else { leaking = Math.min(tank.getFill(), tank.getMaxFill() / 10000); } - + updateLeak(leaking); } } - + tank.unloadTank(4, 5, slots); - + this.networkPackNT(150); } - + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10); ForgeDirection rot = dir.getRotation(ForgeDirection.UP); List players = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 2.875, zCoord + 1).offset(dir.offsetX * 0.5 - rot.offsetX * 2.25, 0, dir.offsetZ * 0.5 - rot.offsetZ * 2.25)); - + for(EntityPlayer player : players) { HbmPlayerProps props = HbmPlayerProps.getData(player); props.isOnLadder = true; } } + protected FluidNode createNode(FluidType type) { + DirPos[] conPos = getConPos(); + + HashSet posSet = new HashSet<>(); + posSet.add(new BlockPos(this)); + for(DirPos pos : conPos) { + ForgeDirection dir = pos.getDir(); + posSet.add(new BlockPos(pos.getX() - dir.offsetX, pos.getY() - dir.offsetY, pos.getZ() - dir.offsetZ)); + } + + return new FluidNode(type.getNetworkProvider(), posSet.toArray(new BlockPos[posSet.size()])).setConnections(conPos); + } + + @Override + public void invalidate() { + super.invalidate(); + + if(!worldObj.isRemote) { + if(this.node != null) { + UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); + } + } + } + @Override public void serialize(ByteBuf buf) { super.serialize(buf); @@ -173,7 +223,7 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements buf.writeBoolean(hasExploded); tank.serialize(buf); } - + @Override public void deserialize(ByteBuf buf) { super.deserialize(buf); @@ -181,39 +231,39 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements hasExploded = buf.readBoolean(); tank.deserialize(buf); } - + /** called when the tank breaks due to hazardous materials or external force, can be used to quickly void part of the tank or spawn a mushroom cloud */ public void explode() { this.hasExploded = true; this.onFire = tank.getTankType().hasTrait(FT_Flammable.class); this.markChanged(); } - + /** called every tick post explosion, used for leaking fluid and spawning particles */ public void updateLeak(int amount) { if(!hasExploded) return; if(amount <= 0) return; - + this.tank.getTankType().onFluidRelease(this, tank, amount); this.tank.setFill(Math.max(0, this.tank.getFill() - amount)); - + FluidType type = tank.getTankType(); - + if(type.hasTrait(FT_Amat.class)) { new ExplosionVNT(worldObj, xCoord + 0.5, yCoord + 1.5, zCoord + 0.5, 5F).makeAmat().setBlockAllocator(null).setBlockProcessor(null).explode(); - + } else if(type.hasTrait(FT_Flammable.class) && onFire) { List affected = worldObj.getEntitiesWithinAABB(Entity.class, AxisAlignedBB.getBoundingBox(xCoord - 1.5, yCoord, zCoord - 1.5, xCoord + 2.5, yCoord + 5, zCoord + 2.5)); for(Entity e : affected) e.setFire(5); Random rand = worldObj.rand; ParticleUtil.spawnGasFlame(worldObj, xCoord + rand.nextDouble(), yCoord + 0.5 + rand.nextDouble(), zCoord + rand.nextDouble(), rand.nextGaussian() * 0.2, 0.1, rand.nextGaussian() * 0.2); - + if(worldObj.getTotalWorldTime() % 5 == 0) { FT_Polluting.pollute(worldObj, xCoord, yCoord, zCoord, tank.getTankType(), FluidReleaseType.BURN, amount * 5); } - + } else if(type.hasTrait(FT_Gaseous.class) || type.hasTrait(FT_Gaseous_ART.class)) { - + if(worldObj.getTotalWorldTime() % 5 == 0) { NBTTagCompound data = new NBTTagCompound(); data.setString("type", "tower"); @@ -233,7 +283,7 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements @Override public void explode(World world, int x, int y, int z) { - + if(this.hasExploded) return; this.onFire = tank.getTankType().hasTrait(FT_Flammable.class); this.hasExploded = true; @@ -243,7 +293,7 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements @Override public void tryExtinguish(World world, int x, int y, int z, EnumExtinguishType type) { if(!this.hasExploded || !this.onFire) return; - + if(type == EnumExtinguishType.WATER) { if(tank.getTankType().hasTrait(FT_Liquid.class)) { // extinguishing oil with water is a terrible idea! worldObj.newExplosion(null, xCoord + 0.5, yCoord + 1.5, zCoord + 0.5, 5F, true, true); @@ -253,13 +303,13 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements return; } } - + if(type == EnumExtinguishType.FOAM || type == EnumExtinguishType.CO2) { this.onFire = false; this.markChanged(); } } - + protected DirPos[] getConPos() { return new DirPos[] { new DirPos(xCoord + 2, yCoord, zCoord - 1, Library.POS_X), @@ -272,17 +322,17 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements new DirPos(xCoord + 1, yCoord, zCoord - 2, Library.NEG_Z) }; } - + public void handleButtonPacket(int value, int meta) { mode = (short) ((mode + 1) % modes); this.markChanged(); } - + AxisAlignedBB bb = null; - + @Override public AxisAlignedBB getRenderBoundingBox() { - + if(bb == null) { bb = AxisAlignedBB.getBoundingBox( xCoord - 2, @@ -293,30 +343,30 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements zCoord + 3 ); } - + return bb; } - + @Override @SideOnly(Side.CLIENT) public double getMaxRenderDistanceSquared() { return 65536.0D; } - + @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); - + mode = nbt.getShort("mode"); tank.readFromNBT(nbt, "tank"); hasExploded = nbt.getBoolean("exploded"); onFire = nbt.getBoolean("onFire"); } - + @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); - + nbt.setShort("mode", mode); tank.writeToNBT(nbt, "tank"); nbt.setBoolean("exploded", hasExploded); @@ -362,6 +412,8 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements this.onFire = data.getBoolean("onFire"); } + @Override public boolean canConnect(FluidType fluid, ForgeDirection dir) { return true; } + @Override public FluidTank[] getSendingTanks() { if(this.hasExploded) return new FluidTank[0]; @@ -370,7 +422,7 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements @Override public FluidTank[] getReceivingTanks() { - if(this.hasExploded || this.sendingBrake) return new FluidTank[0]; + if(this.hasExploded) return new FluidTank[0]; return (mode == 0 || mode == 1) ? new FluidTank[] {tank} : new FluidTank[0]; } @@ -404,14 +456,14 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements public boolean isDamaged() { return this.hasExploded; } - + List repair = new ArrayList<>(); @Override public List getRepairMaterials() { - + if(!repair.isEmpty()) return repair; - + repair.add(new OreDictStack(OreDictManager.STEEL.plate(), 6)); return repair; }