package slimeknights.tconstruct.tools.common.inventory; import com.google.common.collect.Lists; import com.google.common.collect.Queues; import com.google.common.collect.Sets; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.inventory.IInventory; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.lang3.tuple.Pair; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Queue; import java.util.Set; import slimeknights.mantle.inventory.ContainerMultiModule; import slimeknights.tconstruct.tools.common.block.BlockToolTable; import slimeknights.tconstruct.tools.common.block.ITinkerStationBlock; import slimeknights.tconstruct.tools.common.client.GuiTinkerStation; public class ContainerTinkerStation<T extends TileEntity & IInventory> extends ContainerMultiModule<T> { public final boolean hasCraftingStation; public final List<Pair<BlockPos, IBlockState>> tinkerStationBlocks; public ContainerTinkerStation(T tile) { super(tile); tinkerStationBlocks = Lists.newLinkedList(); hasCraftingStation = detectedTinkerStationParts(tile.getWorld(), tile.getPos()); } @SuppressWarnings("unchecked") public <TE extends TileEntity> TE getTinkerTE(Class<TE> clazz) { for(Pair<BlockPos, IBlockState> pair : tinkerStationBlocks) { TileEntity te = this.world.getTileEntity(pair.getLeft()); if(te != null && clazz.isAssignableFrom(te.getClass())) { return (TE) te; } } return null; } public boolean detectedTinkerStationParts(World world, BlockPos start) { Set<Integer> found = Sets.newHashSet(); Set<BlockPos> visited = Sets.newHashSet(); Set<IBlockState> ret = Sets.newHashSet(); boolean hasMaster = false; // BFS for related blocks Queue<BlockPos> queue = Queues.newPriorityQueue(); queue.add(start); while(!queue.isEmpty()) { BlockPos pos = queue.poll(); // already visited between adding and call if(visited.contains(pos)) { continue; } IBlockState state = world.getBlockState(pos); if(!(state.getBlock() instanceof ITinkerStationBlock)) { // not a valid block for us continue; } // found a part, add surrounding blocks that haven't been visited yet if(!visited.contains(pos.north())) { queue.add(pos.north()); } if(!visited.contains(pos.east())) { queue.add(pos.east()); } if(!visited.contains(pos.south())) { queue.add(pos.south()); } if(!visited.contains(pos.west())) { queue.add(pos.west()); } // add to visited visited.add(pos); // save the thing ITinkerStationBlock tinker = (ITinkerStationBlock) state.getBlock(); Integer number = tinker.getGuiNumber(state); if(!found.contains(number)) { found.add(number); tinkerStationBlocks.add(Pair.of(pos, state)); ret.add(state); if(state.getProperties().containsKey(BlockToolTable.TABLES)) { BlockToolTable.TableTypes type = state.getValue(BlockToolTable.TABLES); if(type != null && type == BlockToolTable.TableTypes.CraftingStation) { hasMaster = true; } } } } // sort the found blocks by priority TinkerBlockComp comp = new TinkerBlockComp(); Collections.sort(tinkerStationBlocks, comp); /* if(!hasMaster || foundBlocks.size() < 2) { // sort all the blocks according to their number TinkerBlockComp comp = new TinkerBlockComp(world); foundBlocks.sort(comp); for(BlockPos pos : foundBlocks) { IBlockState state = world.getBlockState(pos); ItemStack stack = state.getBlock().getDrops(world, pos, state, 0).get(0); tinkerTabs.addTab(stack, pos); } }*/ return hasMaster; } /** Tells the client to take the current state and update its info displays */ public void updateGUI() { if(tile.getWorld().isRemote) { Minecraft.getMinecraft().addScheduledTask(new Runnable() { @Override public void run() { ContainerTinkerStation.clientGuiUpdate(); } }); } } /** Tells the client to display the LOCALIZED error message */ public void error(final String message) { if(tile.getWorld().isRemote) { Minecraft.getMinecraft().addScheduledTask(new Runnable() { @Override public void run() { ContainerTinkerStation.clientError(message); } }); } } /** Tells the client to display the LOCALIZED warning message */ public void warning(final String message) { if(tile.getWorld().isRemote) { Minecraft.getMinecraft().addScheduledTask(new Runnable() { @Override public void run() { ContainerTinkerStation.clientWarning(message); } }); } } @SideOnly(Side.CLIENT) private static void clientGuiUpdate() { GuiScreen screen = Minecraft.getMinecraft().currentScreen; if(screen instanceof GuiTinkerStation) { ((GuiTinkerStation) screen).updateDisplay(); } } @SideOnly(Side.CLIENT) private static void clientError(String message) { GuiScreen screen = Minecraft.getMinecraft().currentScreen; if(screen instanceof GuiTinkerStation) { ((GuiTinkerStation) screen).error(message); } } @SideOnly(Side.CLIENT) private static void clientWarning(String message) { GuiScreen screen = Minecraft.getMinecraft().currentScreen; if(screen instanceof GuiTinkerStation) { ((GuiTinkerStation) screen).warning(message); } } private static class TinkerBlockComp implements Comparator<Pair<BlockPos, IBlockState>> { @Override public int compare(Pair<BlockPos, IBlockState> o1, Pair<BlockPos, IBlockState> o2) { IBlockState s1 = o1.getRight(); IBlockState s2 = o2.getRight(); return ((ITinkerStationBlock) s2.getBlock()).getGuiNumber(s2) - ((ITinkerStationBlock) s1.getBlock()).getGuiNumber(s1); } } }