@Override public boolean containsConnection(Class<? extends IConduit> type, ForgeDirection dir) { IConduit con = getConduit(type); if (con != null) { return con.containsConduitConnection(dir); } return false; }
@Override public Set<ForgeDirection> getAllConnections() { EnumSet<ForgeDirection> result = EnumSet.noneOf(ForgeDirection.class); for (IConduit con : conduits) { result.addAll(con.getConduitConnections()); } return result; }
@Method(modid = "ImmibisMicroblocks") private void addConnection(ForgeDirection dir, IConduit c, IConduit connectingTo) { if (connectingTo != null) { if (!c.getConduitConnections().contains(dir) && connectingTo.canConnectToConduit(dir, c)) { c.conduitConnectionAdded(dir); } } }
@Override public Set<ForgeDirection> getConnections(Class<? extends IConduit> type) { IConduit con = getConduit(type); if (con != null) { return con.getConduitConnections(); } return null; }
@Override public boolean containsConnection(ForgeDirection dir) { for (IConduit con : conduits) { if (con.containsConduitConnection(dir)) { return true; } } return false; }
@Override public void addConduit(IConduit conduit) { if (worldObj.isRemote) { return; } conduits.add(conduit); conduit.setBundle(this); conduit.onAddedToBundle(); dirty(); }
@Override public void onNeighborBlockChange(Block blockId) { boolean needsUpdate = false; for (IConduit conduit : conduits) { needsUpdate |= conduit.onNeighborBlockChange(blockId); } if (needsUpdate) { dirty(); } }
@Override public void onNeighborChange( IBlockAccess world, int x, int y, int z, int tileX, int tileY, int tileZ) { boolean needsUpdate = false; for (IConduit conduit : conduits) { needsUpdate |= conduit.onNeighborChange(world, x, y, z, tileX, tileY, tileZ); } if (needsUpdate) { dirty(); } }
public void removeConduit(IConduit conduit, boolean notify) { if (worldObj.isRemote) { return; } conduit.onRemovedFromBundle(); conduits.remove(conduit); conduit.setBundle(null); if (notify) { dirty(); } }
private int getConnectionCount(ForgeDirection dir) { if (dir == ForgeDirection.UNKNOWN) { return conduits.size(); } int result = 0; for (IConduit con : conduits) { if (con.containsConduitConnection(dir) || con.containsExternalConnection(dir)) { result++; } } return result; }
private void addConduitCores(List<CollidableComponent> result, IConduit con) { CollidableCache cc = CollidableCache.instance; Class<? extends IConduit> type = con.getCollidableType(); if (con.hasConnections()) { for (ForgeDirection dir : con.getExternalConnections()) { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), dir), ForgeDirection.UNKNOWN, false), con)); } for (ForgeDirection dir : con.getConduitConnections()) { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), dir), ForgeDirection.UNKNOWN, false), con)); } } else { result.addAll( cc.getCollidables( cc.createKey( type, getOffset(con.getBaseConduitType(), ForgeDirection.UNKNOWN), ForgeDirection.UNKNOWN, false), con)); } }
@Override public void doUpdate() { for (IConduit conduit : conduits) { conduit.updateEntity(worldObj); } if (conduitsDirty) { doConduitsDirty(); } if (facadeChanged) { doFacadeChanged(); } // client side only, check for changes in rendering of the bundle if (worldObj.isRemote) { updateEntityClient(); } }
@Method(modid = "ImmibisMicroblocks") private void updateConnections(ForgeDirection dir, boolean remove) { TileEntity neighbor = getLocation().getLocation(dir).getTileEntity(worldObj); IConduitBundle neighborBundle = (IConduitBundle) (neighbor instanceof IConduitBundle ? neighbor : null); for (IConduit c : getConduits()) { if (remove) { removeConnection(dir, c); } else if (neighborBundle != null) { addConnection(dir, c, neighborBundle.getConduit(c.getBaseConduitType())); } c.connectionsChanged(); } dir = dir.getOpposite(); if (neighbor instanceof IConduitBundle) { for (IConduit c : ((TileConduitBundle) neighbor).getConduits()) { if (remove) { removeConnection(dir, c); } else if (neighborBundle != null) { addConnection(dir, c, getConduit(c.getBaseConduitType())); } c.connectionsChanged(); } } }
@Override public List<CollidableComponent> getCollidableComponents() { for (IConduit con : conduits) { collidablesDirty = collidablesDirty || con.haveCollidablesChangedSinceLastCall(); } if (collidablesDirty) { connectorsDirty = true; } if (!collidablesDirty && !cachedCollidables.isEmpty()) { return cachedCollidables; } cachedCollidables.clear(); for (IConduit conduit : conduits) { cachedCollidables.addAll(conduit.getCollidableComponents()); } addConnectors(cachedCollidables); collidablesDirty = false; return cachedCollidables; }
@Override public void readCustomNBT(NBTTagCompound nbtRoot) { short nbtVersion = nbtRoot.getShort("nbtVersion"); conduits.clear(); cachedCollidables.clear(); NBTTagList conduitTags = (NBTTagList) nbtRoot.getTag("conduits"); if (conduitTags != null) { for (int i = 0; i < conduitTags.tagCount(); i++) { NBTTagCompound conduitTag = conduitTags.getCompoundTagAt(i); IConduit conduit = ConduitUtil.readConduitFromNBT(conduitTag, nbtVersion); if (conduit != null) { conduit.setBundle(this); conduits.add(conduit); } } } String fs = nbtRoot.getString("facadeId"); if (fs == null || "null".equals(fs)) { facadeId = null; facadeType = FacadeType.BASIC; } else { facadeId = Block.getBlockFromName(fs); if (nbtRoot.hasKey("facadeType")) { // backwards compat, never true in freshly placed bundles facadeType = FacadeType.valueOf(nbtRoot.getString("facadeType")); } } facadeMeta = nbtRoot.getInteger("facadeMeta"); if (worldObj != null && worldObj.isRemote) { clientUpdated = true; } if (MicroblocksUtil.supportMicroblocks()) { readMicroblocksFromNBT(nbtRoot); } }
private void addConnectors(List<CollidableComponent> result) { if (conduits.isEmpty()) { return; } for (IConduit con : conduits) { boolean b = con.haveCollidablesChangedSinceLastCall(); collidablesDirty = collidablesDirty || b; connectorsDirty = connectorsDirty || b; } if (!connectorsDirty && !cachedConnectors.isEmpty()) { result.addAll(cachedConnectors); return; } cachedConnectors.clear(); // TODO: What an unholly mess! List<CollidableComponent> coreBounds = new ArrayList<CollidableComponent>(); for (IConduit con : conduits) { addConduitCores(coreBounds, con); } cachedConnectors.addAll(coreBounds); result.addAll(coreBounds); // 1st algorithm List<CollidableComponent> conduitsBounds = new ArrayList<CollidableComponent>(); for (IConduit con : conduits) { conduitsBounds.addAll(con.getCollidableComponents()); addConduitCores(conduitsBounds, con); } Set<Class<IConduit>> collidingTypes = new HashSet<Class<IConduit>>(); for (CollidableComponent conCC : conduitsBounds) { for (CollidableComponent innerCC : conduitsBounds) { if (!InsulatedRedstoneConduit.COLOR_CONTROLLER_ID.equals(innerCC.data) && !InsulatedRedstoneConduit.COLOR_CONTROLLER_ID.equals(conCC.data) && conCC != innerCC && conCC.bound.intersects(innerCC.bound)) { collidingTypes.add((Class<IConduit>) conCC.conduitType); } } } // TODO: Remove the core geometries covered up by this as no point in rendering these if (!collidingTypes.isEmpty()) { List<CollidableComponent> colCores = new ArrayList<CollidableComponent>(); for (Class<IConduit> c : collidingTypes) { IConduit con = getConduit(c); if (con != null) { addConduitCores(colCores, con); } } BoundingBox bb = null; for (CollidableComponent cBB : colCores) { if (bb == null) { bb = cBB.bound; } else { bb = bb.expandBy(cBB.bound); } } if (bb != null) { bb = bb.scale(1.05, 1.05, 1.05); CollidableComponent cc = new CollidableComponent( null, bb, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } } // 2nd algorithm for (IConduit con : conduits) { if (con.hasConnections()) { List<CollidableComponent> cores = new ArrayList<CollidableComponent>(); addConduitCores(cores, con); if (cores.size() > 1) { BoundingBox bb = cores.get(0).bound; float area = bb.getArea(); for (CollidableComponent cc : cores) { bb = bb.expandBy(cc.bound); } if (bb.getArea() > area * 1.5f) { bb = bb.scale(1.05, 1.05, 1.05); CollidableComponent cc = new CollidableComponent( null, bb, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } } } } // Merge all internal conduit connectors into one box BoundingBox conBB = null; for (int i = 0; i < result.size(); i++) { CollidableComponent cc = result.get(i); if (cc.conduitType == null && cc.data == ConduitConnectorType.INTERNAL) { conBB = conBB == null ? cc.bound : conBB.expandBy(cc.bound); result.remove(i); i--; cachedConnectors.remove(cc); } } if (conBB != null) { CollidableComponent cc = new CollidableComponent( null, conBB, ForgeDirection.UNKNOWN, ConduitConnectorType.INTERNAL); result.add(cc); cachedConnectors.add(cc); } // External Connectors EnumSet<ForgeDirection> externalDirs = EnumSet.noneOf(ForgeDirection.class); for (IConduit con : conduits) { Set<ForgeDirection> extCons = con.getExternalConnections(); if (extCons != null) { for (ForgeDirection dir : extCons) { if (con.getConnectionMode(dir) != ConnectionMode.DISABLED) { externalDirs.add(dir); } } } } for (ForgeDirection dir : externalDirs) { BoundingBox bb = ConduitGeometryUtil.instance.getExternalConnectorBoundingBox(dir); CollidableComponent cc = new CollidableComponent(null, bb, dir, ConduitConnectorType.EXTERNAL); result.add(cc); cachedConnectors.add(cc); } connectorsDirty = false; }
@Override public void onChunkUnload() { for (IConduit conduit : conduits) { conduit.onChunkUnload(worldObj); } }
@Method(modid = "ImmibisMicroblocks") private void removeConnection(ForgeDirection dir, IConduit c) { if (c.getConduitConnections().contains(dir)) { c.conduitConnectionRemoved(dir); } }