package WayofTime.alchemicalWizardry.common.tileEntity; import WayofTime.alchemicalWizardry.api.ColourAndCoords; import WayofTime.alchemicalWizardry.api.alchemy.energy.*; import WayofTime.alchemicalWizardry.common.Int3; import WayofTime.alchemicalWizardry.common.entity.projectile.EntityParticleBeam; import WayofTime.alchemicalWizardry.common.spell.complex.effect.SpellHelper; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants; import net.minecraftforge.common.util.ForgeDirection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class TEReagentConduit extends TileSegmentedReagentHandler { public List destinationList; //These are offsets public Map> reagentTargetList; public Map reagentTankDesignationList; public int tickRate = 20; //Rate that the reagents are sent int hasChanged = 0; public boolean affectedByRedstone = true; public int maxConnextions = 5; public int renderCount = 0; public TEReagentConduit() { this(2, 2000); } public TEReagentConduit(int numberOfTanks, int size) { super(numberOfTanks, size); destinationList = new LinkedList(); reagentTargetList = new HashMap(); reagentTankDesignationList = new HashMap(); } public Int3 getColour() { int[] redMap = new int[this.tanks.length]; int[] greenMap = new int[this.tanks.length]; int[] blueMap = new int[this.tanks.length]; for (int i = 0; i < this.tanks.length; i++) { ReagentContainer container = this.tanks[i]; if (container != null && container.getReagent() != null) { Reagent reagent = container.getReagent().reagent; redMap[i] = reagent.getColourRed(); greenMap[i] = reagent.getColourGreen(); blueMap[i] = reagent.getColourBlue(); } } int red = 0; int green = 0; int blue = 0; for (int i = 0; i < this.tanks.length; i++) { red += redMap[i]; green += greenMap[i]; blue += blueMap[i]; } red /= this.tanks.length; green /= this.tanks.length; blue /= this.tanks.length; return new Int3(red, green, blue); } @Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tag.setInteger("hasChanged", hasChanged); NBTTagList tagList = new NBTTagList(); for (int i = 0; i < destinationList.size(); i++) { NBTTagCompound savedTag = new NBTTagCompound(); tagList.appendTag(destinationList.get(i).writeToNBT(savedTag)); } tag.setTag("destinationList", tagList); NBTTagList reagentTagList = new NBTTagList(); //TODO for (Entry> entry : reagentTargetList.entrySet()) { NBTTagCompound savedTag = new NBTTagCompound(); savedTag.setString("reagent", ReagentRegistry.getKeyForReagent(entry.getKey())); NBTTagList coordinateTagList = new NBTTagList(); for (Int3 coord : entry.getValue()) { NBTTagCompound coordinateTag = new NBTTagCompound(); coord.writeToNBT(coordinateTag); coordinateTagList.appendTag(coordinateTag); } savedTag.setTag("coordinateList", coordinateTagList); reagentTagList.appendTag(savedTag); } tag.setTag("reagentTargetList", reagentTagList); NBTTagList tankDesignationList = new NBTTagList(); for (Entry entry : this.reagentTankDesignationList.entrySet()) { NBTTagCompound savedTag = new NBTTagCompound(); savedTag.setString("reagent", ReagentRegistry.getKeyForReagent(entry.getKey())); savedTag.setInteger("integer", entry.getValue()); tankDesignationList.appendTag(savedTag); } tag.setTag("tankDesignationList", tankDesignationList); } @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); hasChanged = tag.getInteger("hasChanged"); NBTTagList tagList = tag.getTagList("destinationList", Constants.NBT.TAG_COMPOUND); destinationList = new LinkedList(); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound savedTag = tagList.getCompoundTagAt(i); destinationList.add(ColourAndCoords.readFromNBT(savedTag)); } reagentTargetList = new HashMap(); NBTTagList reagentTagList = tag.getTagList("reagentTargetList", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < reagentTagList.tagCount(); i++) { NBTTagCompound savedTag = reagentTagList.getCompoundTagAt(i); Reagent reagent = ReagentRegistry.getReagentForKey(savedTag.getString("reagent")); List coordList = new LinkedList(); NBTTagList coordinateList = savedTag.getTagList("coordinateList", Constants.NBT.TAG_COMPOUND); for (int j = 0; j < coordinateList.tagCount(); j++) { coordList.add(Int3.readFromNBT(coordinateList.getCompoundTagAt(j))); } reagentTargetList.put(reagent, coordList); } reagentTankDesignationList = new HashMap(); NBTTagList tankDesignationList = tag.getTagList("tankDesignationList", Constants.NBT.TAG_COMPOUND); for (int i = 0; i < tankDesignationList.tagCount(); i++) { NBTTagCompound savedTag = tankDesignationList.getCompoundTagAt(i); this.reagentTankDesignationList.put(ReagentRegistry.getReagentForKey(savedTag.getString("reagent")), new Integer(savedTag.getInteger("integer"))); } } public void readClientNBT(NBTTagCompound tag) { NBTTagList tagList = tag.getTagList("destinationList", Constants.NBT.TAG_COMPOUND); destinationList = new LinkedList(); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound savedTag = tagList.getCompoundTagAt(i); destinationList.add(ColourAndCoords.readFromNBT(savedTag)); } NBTTagList reagentTagList = tag.getTagList("reagentTanks", Constants.NBT.TAG_COMPOUND); int size = reagentTagList.tagCount(); this.tanks = new ReagentContainer[size]; for (int i = 0; i < size; i++) { NBTTagCompound savedTag = reagentTagList.getCompoundTagAt(i); this.tanks[i] = ReagentContainer.readFromNBT(savedTag); } } public void writeClientNBT(NBTTagCompound tag) { NBTTagList tagList = new NBTTagList(); for (int i = 0; i < destinationList.size(); i++) { NBTTagCompound savedTag = new NBTTagCompound(); tagList.appendTag(destinationList.get(i).writeToNBT(savedTag)); } tag.setTag("destinationList", tagList); NBTTagList reagentTagList = new NBTTagList(); for (int i = 0; i < this.tanks.length; i++) { NBTTagCompound savedTag = new NBTTagCompound(); if (this.tanks[i] != null) { this.tanks[i].writeToNBT(savedTag); } reagentTagList.appendTag(savedTag); } tag.setTag("reagentTanks", reagentTagList); } @Override public void updateEntity() { if (!worldObj.isRemote) { if (hasChanged > 1) { hasChanged = 1; } else if (hasChanged == 1) { hasChanged = 0; } if (worldObj.getWorldTime() % 100 == 99) { this.updateColourList(); } if (affectedByRedstone && worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) { return; } int totalTransfered = 0; for (Entry> entry : this.reagentTargetList.entrySet()) { for (Int3 coord : entry.getValue()) { if (totalTransfered >= this.tickRate) { break; } ReagentStack maxDrainAmount = this.drain(ForgeDirection.UNKNOWN, new ReagentStack(entry.getKey(), this.tickRate - totalTransfered), false); if (maxDrainAmount == null) { continue; } int amountLeft = maxDrainAmount.amount; if (amountLeft <= 0) { continue; } int x = xCoord + coord.xCoord; int y = yCoord + coord.yCoord; int z = zCoord + coord.zCoord; TileEntity tile = worldObj.getTileEntity(x, y, z); if (tile instanceof IReagentHandler) { int amount = Math.min(((IReagentHandler) tile).fill(ForgeDirection.UNKNOWN, maxDrainAmount, false), amountLeft); if (amount > 0) { amountLeft -= amount; totalTransfered += amount; ReagentStack stack = this.drain(ForgeDirection.UNKNOWN, new ReagentStack(entry.getKey(), amount), true); ((IReagentHandler) tile).fill(ForgeDirection.UNKNOWN, stack, true); } } } } } else { if (affectedByRedstone && worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) { return; } renderCount++; if (worldObj.getWorldTime() % 100 != 0) { return; } this.sendPlayerStuffs(); } } @SideOnly(Side.CLIENT) public void sendPlayerStuffs() { Minecraft mc = Minecraft.getMinecraft(); EntityPlayer player = mc.thePlayer; World world = mc.theWorld; if (SpellHelper.canPlayerSeeAlchemy(player)) { for (ColourAndCoords colourSet : this.destinationList) { if (!(worldObj.getTileEntity(xCoord + colourSet.xCoord, yCoord + colourSet.yCoord, zCoord + colourSet.zCoord) instanceof IReagentHandler)) { continue; } EntityParticleBeam beam = new EntityParticleBeam(worldObj, xCoord + 0.5, yCoord + 0.5, zCoord + 0.5); double velocity = Math.sqrt(Math.pow(colourSet.xCoord, 2) + Math.pow(colourSet.yCoord, 2) + Math.pow(colourSet.zCoord, 2)); double wantedVel = 0.3d; beam.setVelocity(wantedVel * colourSet.xCoord / velocity, wantedVel * colourSet.yCoord / velocity, wantedVel * colourSet.zCoord / velocity); beam.setColour(colourSet.colourRed / 255f, colourSet.colourGreen / 255f, colourSet.colourBlue / 255f); beam.setDestination(xCoord + colourSet.xCoord, yCoord + colourSet.yCoord, zCoord + colourSet.zCoord); worldObj.spawnEntityInWorld(beam); } } } public void updateColourList() { if (worldObj.isRemote) { return; } List newList = this.compileListForReagentTargets(this.reagentTargetList); if (newList != null && !newList.equals(destinationList)) { this.destinationList = newList; worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } } public List compileListForReagentTargets(Map> map) { List list = new LinkedList(); for (Entry> entry : map.entrySet()) { if (entry.getValue() != null) { Reagent reagent = entry.getKey(); if (reagent == null) { continue; } List coords = entry.getValue(); for (Int3 coord : coords) { if (coord == null) { continue; } list.add(new ColourAndCoords(reagent.getColourRed(), reagent.getColourGreen(), reagent.getColourBlue(), reagent.getColourIntensity(), coord.xCoord, coord.yCoord, coord.zCoord)); } } } return list; } public boolean addDestinationViaOffset(int red, int green, int blue, int intensity, int xOffset, int yOffset, int zOffset) { if (xOffset == 0 && yOffset == 0 && zOffset == 0) { return false; } this.destinationList.add(new ColourAndCoords(red, green, blue, intensity, xOffset, yOffset, zOffset)); return true; } public boolean addDestinationViaActual(int red, int green, int blue, int intensity, int x, int y, int z) { return this.addDestinationViaOffset(red, green, blue, intensity, x - this.xCoord, y - this.yCoord, z - this.zCoord); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbttagcompound = new NBTTagCompound(); writeClientNBT(nbttagcompound); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 90210, nbttagcompound); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) { super.onDataPacket(net, packet); readClientNBT(packet.func_148857_g()); } public boolean addReagentDestinationViaOffset(Reagent reagent, int xOffset, int yOffset, int zOffset) { int totalConnections = 0; for (Entry> entry : this.reagentTargetList.entrySet()) { if (entry.getValue() != null) { totalConnections += entry.getValue().size(); } } if (totalConnections >= this.maxConnextions) { //Send message that it cannot be done? Maybe add a Player instance return false; } if (xOffset == 0 && yOffset == 0 && zOffset == 0) { return false; } Int3 newCoord = new Int3(xOffset, yOffset, zOffset); if (this.reagentTargetList.containsKey(reagent)) { List coordList = this.reagentTargetList.get(reagent); if (coordList == null) { List newCoordList = new LinkedList(); newCoordList.add(newCoord); this.reagentTargetList.put(reagent, newCoordList); } else { coordList.add(newCoord); } return true; } else { List newCoordList = new LinkedList(); newCoordList.add(newCoord); this.reagentTargetList.put(reagent, newCoordList); return true; } } public boolean addReagentDestinationViaActual(Reagent reagent, int x, int y, int z) { return (this.addReagentDestinationViaOffset(reagent, x - xCoord, y - yCoord, z - zCoord)); } public boolean removeReagentDestinationViaOffset(Reagent reagent, int xOffset, int yOffset, int zOffset) { if (this.reagentTargetList.containsKey(reagent)) { List coords = this.reagentTargetList.get(reagent); if (coords != null) { Int3 reference = new Int3(xOffset, yOffset, zOffset); return coords.remove(reference); } } return false; } public boolean removeReagentDestinationViaActual(Reagent reagent, int x, int y, int z) { return this.removeReagentDestinationViaOffset(reagent, x - xCoord, y - yCoord, z - zCoord); } @Override public int fill(ForgeDirection from, ReagentStack resource, boolean doFill) { if (doFill && !worldObj.isRemote) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); hasChanged = 2; } return super.fill(from, resource, doFill); } @Override public ReagentStack drain(ForgeDirection from, ReagentStack resource, boolean doDrain) { if (doDrain && !worldObj.isRemote) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); hasChanged = 2; } return super.drain(from, resource, doDrain); } }