@Override public void update() { if (worldObj.isRemote) { return; } // TODO: Ugh, laaaame. Schedule a block update? if (!partsValidated) { partsValidated = true; Iterator<ClayLump> it = parts.iterator(); while (it.hasNext()) { ClayLump lump = it.next(); if (!isValidLump(lump)) { if (parts.size() == 1) { lump.asDefault(); } else { it.remove(); InvUtil.spawnItemStack(getCoord(), new ItemStack(Items.clay_ball)); } } } } if (getState() == ClayState.WET) { if (!worldObj.isRaining()) { lastTouched++; } if (totalHeat > 0) { totalHeat--; lastTouched++; } } if (getState() != lastState) { lastState = getState(); broadcastMessage(null, SculptState, lastState.ordinal()); } }
private void writeParts(NBTTagCompound tag) { NBTTagList l = new NBTTagList(); for (ClayLump lump : parts) { NBTTagCompound rc_tag = new NBTTagCompound(); lump.write(rc_tag); l.appendTag(rc_tag); } tag.setTag("parts", l); }
public ClayLump copy() { ClayLump ret = new ClayLump(); ret.minX = minX; ret.minY = minY; ret.minZ = minZ; ret.maxX = maxX; ret.maxY = maxY; ret.maxZ = maxZ; ret.icon_id = icon_id; ret.icon_md = icon_md; ret.quat = new Quaternion(quat); return ret; }
private void updateLump(int id, ClayLump lump) { if (id < 0 || id >= parts.size()) { return; } ClayLump old = parts.get(id); if (old.equals(lump)) { return; } parts.set(id, lump); touch(); if (worldObj.isRemote) { return; } }
@SubscribeEvent @SideOnly(Side.CLIENT) public void renderCeramicsSelection(DrawBlockHighlightEvent event) { if (event.target.subHit == -1) { return; } Coord c = Coord.fromMop(event.player.worldObj, event.target); TileEntityGreenware clay = c.getTE(TileEntityGreenware.class); if (clay == null) { return; } if (event.target.subHit < 0 || event.target.subHit >= clay.parts.size()) { return; } event.setCanceled(true); EntityPlayer player = event.player; double partial = event.partialTicks; ClayLump lump = clay.parts.get(event.target.subHit); Block block = new Block(Material.rock); lump.toRotatedBlockBounds(clay, block); double widen = 0.002; double oX = player.lastTickPosX + (player.posX - player.lastTickPosX) * partial; double oY = player.lastTickPosY + (player.posY - player.lastTickPosY) * partial; double oZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partial; AxisAlignedBB bb = block .getSelectedBoundingBox(c.w, c.toBlockPos()) .expand(widen, widen, widen) .offset(-oX, -oY, -oZ); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glDepthMask(false); float r = 0xFF; GL11.glLineWidth(2.0F); GL11.glColor4f(0, 0, 0, 0.4F); // GL11.glColor4f(0x4D/r, 0x34/r, 0x7C/r, 0.8F); //#4D347C RenderGlobal.drawSelectionBoundingBox(bb); GL11.glDepthMask(true); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_BLEND); // TODO: If the rotation tool is selected, may draw the axis? // Oooooh, we could also draw the offset position for *EVERY* tool... }
ClayLump extrudeLump(ClayLump against, EnumFacing dir) { ClayLump lump = against.copy(); Block b = FzUtil.getTraceHelper(); against.toBlockBounds(b); int wX = lump.maxX - lump.minX; int wY = lump.maxY - lump.minY; int wZ = lump.maxZ - lump.minZ; lump.maxX += wX * dir.getDirectionVec().getX(); lump.maxY += wY * dir.getDirectionVec().getY(); lump.maxZ += wZ * dir.getDirectionVec().getZ(); lump.minX += wX * dir.getDirectionVec().getX(); lump.minY += wY * dir.getDirectionVec().getY(); lump.minZ += wZ * dir.getDirectionVec().getZ(); return lump; }
@Override public boolean addCollisionBoxesToList( Block ignore, AxisAlignedBB aabb, List<AxisAlignedBB> list, Entity entity) { Block block = new Block(Material.rock); ClayState state = getState(); if (state == ClayState.WET) { block.setBlockBounds(0, 0, 0, 1, 1F / 8F, 1); AxisAlignedBB a = block.getCollisionBoundingBox(worldObj, pos, null); if (aabb.intersectsWith(a)) { list.add(a); } } for (ClayLump lump : parts) { lump.toRotatedBlockBounds(this, block); AxisAlignedBB a = block.getCollisionBoundingBox(worldObj, pos, null); if (aabb.intersectsWith(a)) { list.add(a); } } return true; }
@Override public MovingObjectPosition collisionRayTrace(Vec3 startVec, Vec3 endVec) { Block block = new Block(Material.rock); // It's possible for the startVec to be embedded in a lump (causing it // to hit the opposite side), so we must move it farther away Vec3 d = startVec.subtract(endVec); double scale = 5.2; // Diagonal of a 3³. (Was initially using incrScale = 2) // This isn't quite right; the dVector would properly be normalized here // & rescaled to the max diameter. But we can survive without it. // Unnormalized length of dVector is 6m in surviavl mode IIRC. This'll // be way longer than it needs to be. // Why is it + instead of -? Hmm. startVec = startVec.add(SpaceUtil.scale(d, scale)); MovingObjectPosition shortest = null; for (int i = 0; i < parts.size(); i++) { ClayLump lump = parts.get(i); lump.toRotatedBlockBounds(this, block); MovingObjectPosition mop = block.collisionRayTrace(worldObj, pos, startVec, endVec); if (mop != null) { mop.subHit = i; if (shortest == null) { shortest = mop; } else { Vec3 s = shortest.hitVec; Vec3 m = mop.hitVec; s = new Vec3(s.xCoord, s.yCoord, s.zCoord); m = new Vec3(m.xCoord, m.yCoord, m.zCoord); startVec = startVec.subtract(s).subtract(m); if (m.lengthVector() < s.lengthVector()) { shortest = mop; } } } } return shortest; // return super.collisionRayTrace(w, pos, startVec, endVec); }
private void shareLump(int id, ClayLump selection) { ArrayList<Object> toSend = new ArrayList(); toSend.add(id); selection.write(toSend); broadcastMessage(null, SculptMove, toSend.toArray()); }
public boolean isValidLump(ClayLump lump) { // check volume if (!(Core.cheat)) { int wX = lump.maxX - lump.minX; int wY = lump.maxY - lump.minY; int wZ = lump.maxZ - lump.minZ; int area = wX * wY * wZ; int max_area = 16 * 16 * 16 /* / 4 */; if (!FzConfig.stretchy_clay) { max_area /= 4; } if (area <= 0 || area > max_area) { return false; } } // check bounds final int B = 16 * 3; if (lump.minX < 0) return false; if (lump.minY < 0) return false; if (lump.minZ < 0) return false; if (lump.maxX > B) return false; if (lump.maxY > B) return false; if (lump.maxZ > B) return false; // check for free space (needs to be last, as it can mutate the world) Block block = FzUtil.getTraceHelper(); for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { for (int dz = -1; dz <= 1; dz++) { AxisAlignedBB ab = new AxisAlignedBB( pos.getX() + dx, pos.getY() + dy, pos.getZ() + dz, pos.getX() + dx + 1, pos.getY() + dy + 1, pos.getZ() + dz + 1); Coord c = getCoord(); c.x += dx; c.y += dy; c.z += dz; lump.toRotatedBlockBounds(this, block); AxisAlignedBB in = block.getCollisionBoundingBox(worldObj, pos, c.getState()); if (in != null && ab.intersectsWith(in)) { // This block needs to be an Extension, or this if (c.isAir() || c.isReplacable()) { c.setId(Core.registry.legacy_factory_block); TileEntityExtension tex = new TileEntityExtension(this); c.setTE(tex); tex.getBlockClass().enforce(c); continue; } TileEntity te = c.getTE(); if (te == this) { continue; } if (te instanceof TileEntityExtension) { TileEntityExtension tex = (TileEntityExtension) te; if (tex.getParent() == this) { continue; } } // We used to not allow this. We just make a bit of noise instead. // A notification will indicate that things will be a bit messed up here. // FIXME: Let block collision boxes go outside the block (Notch hard-coded for fences) new Notice(c, "!").sendToAll(); } } } } return true; }