package WayofTime.alchemicalWizardry.common.tileEntity; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; 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 WayofTime.alchemicalWizardry.api.ColourAndCoords; import WayofTime.alchemicalWizardry.api.alchemy.energy.IReagentHandler; import WayofTime.alchemicalWizardry.api.alchemy.energy.Reagent; import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentContainer; import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentStack; import WayofTime.alchemicalWizardry.api.alchemy.energy.TileSegmentedReagentHandler; 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; 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> 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 coordList = new LinkedList(); NBTTagList coordinateList = savedTag.getTagList("coordinateList", Constants.NBT.TAG_COMPOUND); for(int j=0; j 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); } }