mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-02-22 05:50:49 +00:00
206 lines
5.9 KiB
Java
206 lines
5.9 KiB
Java
package com.hbm.tileentity.machine;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import com.hbm.blocks.ModBlocks;
|
|
import com.hbm.blocks.machine.FoundryChannel.FoundryNode;
|
|
import com.hbm.inventory.material.MaterialShapes;
|
|
import com.hbm.inventory.material.Mats.MaterialStack;
|
|
import com.hbm.lib.Library;
|
|
import com.hbm.uninos.UniNodespace;
|
|
import com.hbm.uninos.networkproviders.FoundryNetworkProvider;
|
|
import com.hbm.util.fauxpointtwelve.BlockPos;
|
|
import com.hbm.util.fauxpointtwelve.DirPos;
|
|
|
|
import api.hbm.block.ICrucibleAcceptor;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.world.World;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
public class TileEntityFoundryChannel extends TileEntityFoundryBase {
|
|
|
|
public int nextUpdate;
|
|
public int lastFlow = 0;
|
|
|
|
protected FoundryNode node;
|
|
|
|
@Override
|
|
public void updateEntity() {
|
|
|
|
if(!worldObj.isRemote) {
|
|
initNode();
|
|
|
|
if(this.node.type != null && this.amount == 0) {
|
|
this.node.type = null;
|
|
}
|
|
|
|
if(this.type == null && this.amount != 0) {
|
|
this.amount = 0;
|
|
}
|
|
|
|
nextUpdate--;
|
|
|
|
if(nextUpdate <= 0 && this.amount > 0 && this.type != null) {
|
|
|
|
boolean hasOp = false;
|
|
nextUpdate = 5;
|
|
|
|
List<Integer> ints = new ArrayList<Integer>() {{ add(2); add(3); add(4); add(5); }};
|
|
Collections.shuffle(ints);
|
|
if(lastFlow > 0) {
|
|
ints.remove((Integer) this.lastFlow);
|
|
ints.add(this.lastFlow);
|
|
}
|
|
|
|
for(Integer i : ints) {
|
|
ForgeDirection dir = ForgeDirection.getOrientation(i);
|
|
Block b = worldObj.getBlock(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ);
|
|
|
|
if(b instanceof ICrucibleAcceptor && b != ModBlocks.foundry_channel) {
|
|
ICrucibleAcceptor acc = (ICrucibleAcceptor) b;
|
|
|
|
if(acc.canAcceptPartialFlow(worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, dir.getOpposite(), new MaterialStack(this.type, this.amount))) {
|
|
MaterialStack left = acc.flow(worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, dir.getOpposite(), new MaterialStack(this.type, this.amount));
|
|
if(left == null) {
|
|
this.type = null;
|
|
this.amount = 0;
|
|
|
|
this.node.type = null;
|
|
} else {
|
|
this.amount = left.amount;
|
|
}
|
|
hasOp = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!hasOp) {
|
|
for(Integer i : ints) {
|
|
ForgeDirection dir = ForgeDirection.getOrientation(i);
|
|
TileEntity b = worldObj.getTileEntity(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ);
|
|
|
|
if(b instanceof TileEntityFoundryChannel) {
|
|
TileEntityFoundryChannel acc = (TileEntityFoundryChannel) b;
|
|
|
|
if(acc.type == null || acc.type == this.type || acc.amount == 0) {
|
|
acc.type = this.type;
|
|
acc.initNode();
|
|
acc.node.type = this.type;
|
|
|
|
acc.lastFlow = dir.getOpposite().ordinal();
|
|
|
|
if(worldObj.rand.nextInt(5) == 0 || this.amount == 1) { //force swap operations with single quanta to keep them moving
|
|
//1:4 chance that the fill states are simply swapped
|
|
//this promotes faster spreading and prevents spread limits
|
|
int buf = this.amount;
|
|
this.amount = acc.amount;
|
|
acc.amount = buf;
|
|
|
|
} else {
|
|
//otherwise, equalize the neighbors
|
|
int diff = this.amount - acc.amount;
|
|
|
|
if(diff > 0) {
|
|
diff /= 2;
|
|
this.amount -= diff;
|
|
acc.amount += diff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(this.amount == 0) {
|
|
this.lastFlow = 0;
|
|
this.nextUpdate = 5;
|
|
}
|
|
}
|
|
|
|
super.updateEntity();
|
|
}
|
|
|
|
protected void initNode() {
|
|
if(this.node == null || this.node.expired) {
|
|
|
|
this.node = (FoundryNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, FoundryNetworkProvider.THE_PROVIDER);
|
|
|
|
if(this.node == null || this.node.expired) {
|
|
this.node = this.createNode();
|
|
this.node.type = this.type;
|
|
UniNodespace.createNode(worldObj, this.node);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getCapacity() {
|
|
return MaterialShapes.INGOT.q(2);
|
|
}
|
|
|
|
@Override
|
|
public void readFromNBT(NBTTagCompound nbt) {
|
|
super.readFromNBT(nbt);
|
|
this.lastFlow = nbt.getByte("flow");
|
|
}
|
|
|
|
@Override
|
|
public void writeToNBT(NBTTagCompound nbt) {
|
|
super.writeToNBT(nbt);
|
|
nbt.setByte("flow", (byte) this.lastFlow);
|
|
}
|
|
|
|
@Override
|
|
public void invalidate() {
|
|
super.invalidate();
|
|
|
|
if(!worldObj.isRemote) {
|
|
if(this.node != null) {
|
|
UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, FoundryNetworkProvider.THE_PROVIDER);
|
|
}
|
|
}
|
|
}
|
|
|
|
public FoundryNode createNode() {
|
|
TileEntity tile = (TileEntity) this;
|
|
return new FoundryNode(FoundryNetworkProvider.THE_PROVIDER, new BlockPos(tile.xCoord, tile.yCoord, tile.zCoord)).setConnections(
|
|
new DirPos(tile.xCoord + 1, tile.yCoord, tile.zCoord, Library.POS_X),
|
|
new DirPos(tile.xCoord - 1, tile.yCoord, tile.zCoord, Library.NEG_X),
|
|
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord + 1, Library.POS_Z),
|
|
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord - 1, Library.NEG_Z)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
public boolean canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack) {
|
|
if(this.node == null || !this.node.hasValidNet()) return false;
|
|
for(Object o : this.node.net.links) {
|
|
FoundryNode node = (FoundryNode) o;
|
|
if(node.type != null && node.type != stack.material) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return super.canAcceptPartialPour(world, x, y, z, dX, dY, dZ, side, stack);
|
|
}
|
|
|
|
@Override
|
|
public MaterialStack flow(World world, int x, int y, int z, ForgeDirection side, MaterialStack stack) {
|
|
if(this.node != null) this.node.type = stack.material;
|
|
return super.flow(world, x, y, z, side, stack);
|
|
}
|
|
|
|
@Override
|
|
public MaterialStack pour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, MaterialStack stack) {
|
|
if(this.node != null) this.node.type = stack.material;
|
|
return super.pour(world, x, y, z, dX, dY, dZ, side, stack);
|
|
}
|
|
|
|
}
|