use of crazypants.enderio.base.conduit.geom.CollidableComponent in project EnderIO by SleepyTrousers.
the class TileConduitBundle method addConnectors.
@SuppressWarnings("unchecked")
private void addConnectors(List<CollidableComponent> result) {
if (getConduits().isEmpty()) {
return;
}
for (IConduit con : getConduits()) {
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! (and it doesn't even work correctly...)
List<CollidableComponent> coreBounds = new ArrayList<CollidableComponent>();
for (IConduit con : getConduits()) {
addConduitCores(coreBounds, con);
}
cachedConnectors.addAll(coreBounds);
result.addAll(coreBounds);
// 1st algorithm
List<CollidableComponent> conduitsBounds = new ArrayList<CollidableComponent>();
for (IConduit con : getConduits()) {
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, null, ConduitConnectorType.INTERNAL);
result.add(cc);
cachedConnectors.add(cc);
}
}
// 2nd algorithm
for (IConduit con : getConduits()) {
if (con.hasConnections()) {
List<CollidableComponent> cores = new ArrayList<CollidableComponent>();
addConduitCores(cores, con);
if (cores.size() > 1) {
BoundingBox bb = cores.get(0).bound;
double 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, null, 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, null, ConduitConnectorType.INTERNAL);
result.add(cc);
cachedConnectors.add(cc);
}
// External Connectors
EnumSet<EnumFacing> externalDirs = EnumSet.noneOf(EnumFacing.class);
for (IConduit con : getConduits()) {
Set<EnumFacing> extCons = con.getExternalConnections();
for (EnumFacing dir : extCons) {
if (con.getConnectionMode(NullHelper.notnull(dir, "IConduit#getExternalConnections#iterator#next")) != ConnectionMode.DISABLED) {
externalDirs.add(dir);
}
}
}
for (EnumFacing dir : externalDirs) {
BoundingBox bb = ConduitGeometryUtil.instance.getExternalConnectorBoundingBox(dir);
if (bb != null) {
CollidableComponent cc = new CollidableComponent(null, bb, dir, ConduitConnectorType.EXTERNAL);
result.add(cc);
cachedConnectors.add(cc);
}
}
connectorsDirty = false;
}
use of crazypants.enderio.base.conduit.geom.CollidableComponent in project EnderIO by SleepyTrousers.
the class EnderLiquidConduit method onBlockActivated.
@Override
public boolean onBlockActivated(@Nonnull EntityPlayer player, @Nonnull EnumHand hand, @Nonnull RaytraceResult res, @Nonnull List<RaytraceResult> all) {
if (Prep.isInvalid(player.getHeldItem(hand))) {
return false;
}
if (ToolUtil.isToolEquipped(player, hand)) {
if (!getBundle().getEntity().getWorld().isRemote) {
final CollidableComponent component = res.component;
if (component != null) {
EnumFacing connDir = component.dir;
EnumFacing faceHit = res.movingObjectPosition.sideHit;
if (connDir == null || connDir == faceHit) {
if (getConnectionMode(faceHit) == ConnectionMode.DISABLED) {
setConnectionMode(faceHit, getNextConnectionMode(faceHit));
return true;
}
BlockPos pos = getBundle().getLocation().offset(faceHit);
ILiquidConduit n = ConduitUtil.getConduit(getBundle().getEntity().getWorld(), pos.getX(), pos.getY(), pos.getZ(), ILiquidConduit.class);
if (n == null) {
return false;
}
if (!(n instanceof EnderLiquidConduit)) {
return false;
}
return ConduitUtil.connectConduits(this, faceHit);
} else if (containsExternalConnection(connDir)) {
// Toggle extraction mode
setConnectionMode(connDir, getNextConnectionMode(connDir));
} else if (containsConduitConnection(connDir)) {
ConduitUtil.disconnectConduits(this, connDir);
}
}
}
return true;
}
return false;
}
Aggregations