public static boolean canTeleportTo(WarpPoint point) { if (point.getY() < 0) return false; Block block1 = point.getWorld().getBlock(point.getBlockX(), point.getBlockY(), point.getBlockZ()); Block block2 = point.getWorld().getBlock(point.getBlockX(), point.getBlockY() + 1, point.getBlockZ()); boolean block1Free = !block1.getMaterial().isSolid() || block1.getBlockBoundsMaxX() < 1 || block1.getBlockBoundsMaxY() > 0; boolean block2Free = !block2.getMaterial().isSolid() || block2.getBlockBoundsMaxX() < 1 || block2.getBlockBoundsMaxY() > 0; return block1Free && block2Free; }
@SideOnly(Side.CLIENT) public static void func_150918_a( World p_150918_0_, int p_150918_1_, int p_150918_2_, int p_150918_3_, int p_150918_4_) { if (p_150918_4_ == 0) { p_150918_4_ = 15; } Block block = p_150918_0_.getBlock(p_150918_1_, p_150918_2_, p_150918_3_); if (block.getMaterial() != Material.air) { block.setBlockBoundsBasedOnState(p_150918_0_, p_150918_1_, p_150918_2_, p_150918_3_); for (int i1 = 0; i1 < p_150918_4_; ++i1) { double d0 = itemRand.nextGaussian() * 0.02D; double d1 = itemRand.nextGaussian() * 0.02D; double d2 = itemRand.nextGaussian() * 0.02D; p_150918_0_.spawnParticle( "happyVillager", (double) ((float) p_150918_1_ + itemRand.nextFloat()), (double) p_150918_2_ + (double) itemRand.nextFloat() * block.getBlockBoundsMaxY(), (double) ((float) p_150918_3_ + itemRand.nextFloat()), d0, d1, d2); } } else { for (int i1 = 0; i1 < p_150918_4_; ++i1) { double d0 = itemRand.nextGaussian() * 0.02D; double d1 = itemRand.nextGaussian() * 0.02D; double d2 = itemRand.nextGaussian() * 0.02D; p_150918_0_.spawnParticle( "happyVillager", (double) ((float) p_150918_1_ + itemRand.nextFloat()), (double) p_150918_2_ + (double) itemRand.nextFloat() * 1.0f, (double) ((float) p_150918_3_ + itemRand.nextFloat()), d0, d1, d2); } } }
private void setBlockBoundsBasedOnSelection(World world, int x, int y, int z) { float m = ConfigurationLib.littleBlocksSize; if (xSelected == -10) { this.setBlockBounds(0f, 0f, 0f, 0f, 0f, 0f); } else { TileEntityLittleChunk tile = (TileEntityLittleChunk) world.getTileEntity(x, y, z); Block block = tile.getBlock(xSelected, ySelected, zSelected); // System.out.println("Content: " + content); if (block == null) { this.setBlockBounds( xSelected / m, ySelected / m, zSelected / m, (xSelected + 1) / m, (ySelected + 1) / m, (zSelected + 1) / m); } else { if (block != null) { if (BlockStairs.func_150148_a /* isBlockStairsID */(block)) { block.setBlockBounds(0, 0, 0, 1, 1, 1); } else { block.setBlockBoundsBasedOnState( tile.getLittleWorld(), (x << 3) + xSelected, (y << 3) + ySelected, (z << 3) + zSelected); } this.setBlockBounds( (float) (xSelected + block.getBlockBoundsMinX()) / m, (float) (ySelected + block.getBlockBoundsMinY()) / m, (float) (zSelected + block.getBlockBoundsMinZ()) / m, (float) (xSelected + block.getBlockBoundsMaxX()) / m, (float) (ySelected + block.getBlockBoundsMaxY()) / m, (float) (zSelected + block.getBlockBoundsMaxZ()) / m); } } } }
@Override public void onUpdate() { if (posY < -500.0D) { setDead(); return; } if (hasGravity) { motionY -= 0.03999999910593033D; } if (hasAirResistance) { motionX *= 0.98; motionY *= 0.98; motionZ *= 0.98; } prevPosX = posX; prevPosY = posY; prevPosZ = posZ; extinguish(); moveEntity(motionX, motionY, motionZ); Block block = getBlock(); if (block == null) setDead(); else setHeight((float) block.getBlockBoundsMaxY()); if (worldObj instanceof WorldServer && shouldPlaceBlock()) { int x = MathHelper.floor_double(posX); int y = MathHelper.floor_double(posY); int z = MathHelper.floor_double(posZ); if (!tryPlaceBlock((WorldServer) worldObj, x, y, z)) dropBlock(); setDead(); } }
@SideOnly(Side.CLIENT) public void spinUpdate(GCEntityClientPlayerMP p) { boolean freefall = true; if (p.boundingBox.maxX >= this.ssBoundsMinX && p.boundingBox.minX <= this.ssBoundsMaxX && p.boundingBox.maxY >= this.ssBoundsMinY && p.boundingBox.minY <= this.ssBoundsMaxY && p.boundingBox.maxZ >= this.ssBoundsMinZ && p.boundingBox.minZ <= this.ssBoundsMaxZ) { // Player is somewhere within the space station boundaries // This is an "on the ground" check int playerFeetOnY = (int) (p.boundingBox.minY - 0.001D); Block b = this.worldObj.getBlock( MathHelper.floor_double(p.posX), playerFeetOnY, MathHelper.floor_double(p.posX)); double blockYmax = b.getBlockBoundsMaxY() + playerFeetOnY; if (b != Blocks.air && p.boundingBox.minY - blockYmax < 0.001D) { freefall = false; } else { // Check if the player's bounding box is in the same block coordinates as any non-vacuum // block (including torches etc) // If so, it's assumed the player has something close enough to grab onto, so is not in // freefall // Note: breatheable air here means the player is definitely not in freefall int xmx = MathHelper.floor_double(p.boundingBox.maxX); int ym = MathHelper.floor_double(p.boundingBox.minY); int yy = MathHelper.floor_double(p.boundingBox.maxY); int zm = MathHelper.floor_double(p.boundingBox.minZ); int zz = MathHelper.floor_double(p.boundingBox.maxZ); BLOCKCHECK: for (int x = MathHelper.floor_double(p.boundingBox.minX); x <= xmx; x++) { for (int y = ym; y <= yy; y++) { for (int z = zm; z <= zz; z++) { if (this.worldObj.getBlock(x, y, z) != Blocks.air) { freefall = false; break BLOCKCHECK; } } } } } /* if (freefall) { //If that check didn't produce a result, see if the player is inside the walls //TODO: could apply special weightless movement here like Coriolis force - the player is inside the walls, not touching them, and in a vacuum int quadrant = 0; double xd = p.posX - this.spinCentreX; double zd = p.posZ - this.spinCentreZ; if (xd<0) { if (xd<-Math.abs(zd)) { quadrant = 2; } else quadrant = (zd<0) ? 3 : 1; } else if (xd>Math.abs(zd)) { quadrant = 0; } else quadrant = (zd<0) ? 3 : 1; int ymin = MathHelper.floor_double(p.boundingBox.minY)-1; int ymax = MathHelper.floor_double(p.boundingBox.maxY); int xmin, xmax, zmin, zmax; switch (quadrant) { case 0: xmin = MathHelper.floor_double(p.boundingBox.maxX); xmax = this.ssBoundsMaxX - 1; zmin = MathHelper.floor_double(p.boundingBox.minZ)-1; zmax = MathHelper.floor_double(p.boundingBox.maxZ)+1; break; case 1: xmin = MathHelper.floor_double(p.boundingBox.minX)-1; xmax = MathHelper.floor_double(p.boundingBox.maxX)+1; zmin = MathHelper.floor_double(p.boundingBox.maxZ); zmax = this.ssBoundsMaxZ - 1; break; case 2: zmin = MathHelper.floor_double(p.boundingBox.minZ)-1; zmax = MathHelper.floor_double(p.boundingBox.maxZ)+1; xmin = this.ssBoundsMinX; xmax = MathHelper.floor_double(p.boundingBox.minX); break; case 3: default: xmin = MathHelper.floor_double(p.boundingBox.minX)-1; xmax = MathHelper.floor_double(p.boundingBox.maxX)+1; zmin = this.ssBoundsMinZ; zmax = MathHelper.floor_double(p.boundingBox.minZ); break; } //This block search could cost a lot of CPU (but client side) - maybe optimise later BLOCKCHECK0: for(int x = xmin; x <= xmax; x++) for (int z = zmin; z <= zmax; z++) for (int y = ymin; y <= ymax; y++) if (this.worldObj.getBlock(x, y, z) != Blocks.air) { freefall = false; break BLOCKCHECK0; } }*/ } boolean doGravity = true; if (freefall) { doGravity = false; // Do spinning if (this.doSpinning && this.angularVelocityRadians != 0F) { // TODO maybe need to test to make sure xx and zz are not too large (outside sight range of // SS) // TODO think about server + network load (loading/unloading chunks) when movement is rapid // Maybe reduce chunkloading radius? float angle; final double xx = p.posX - this.spinCentreX; final double zz = p.posZ - this.spinCentreZ; double arc = Math.sqrt(xx * xx + zz * zz); if (xx == 0D) { angle = zz > 0 ? 3.141592536F / 2 : -3.141592536F / 2; } else { angle = (float) Math.atan(zz / xx); } if (xx < 0D) { angle += 3.141592536F; } angle += this.angularVelocityRadians / 3F; arc = arc * this.angularVelocityRadians; double offsetX = -arc * MathHelper.sin(angle); double offsetZ = arc * MathHelper.cos(angle); // Check for block collisions here - if so move the player appropriately // First check that there are no existing collisions where the player is now (TODO: bounce // the player away) if (this.worldObj.getCollidingBoundingBoxes(p, p.boundingBox).size() == 0) { // Now check for collisions in the new direction and if there are some, try reducing the // movement int collisions = 0; do { List<AxisAlignedBB> list = this.worldObj.getCollidingBoundingBoxes( p, p.boundingBox.addCoord(offsetX, 0.0D, offsetZ)); collisions = list.size(); if (collisions > 0) { if (!doGravity) { p.motionX += -offsetX; p.motionZ += -offsetZ; } offsetX /= 2D; offsetZ /= 2D; if (offsetX < 0.01D && offsetX > -0.01D) { offsetX = 0D; } if (offsetZ < 0.01D && offsetZ > -0.01D) { offsetZ = 0D; } doGravity = true; } } while (collisions > 0); p.posX += offsetX; p.posZ += offsetZ; p.boundingBox.offset(offsetX, 0.0D, offsetZ); } p.rotationYaw += this.skyAngularVelocity; while (p.rotationYaw > 360F) { p.rotationYaw -= 360F; } /* //Just started freefall - give some impulse if (!p.inFreefall && p.inFreefallFirstCheck) { p.motionX += offsetX * 0.91F; p.motionZ += offsetZ * 0.91F; }*/ } // Reverse effects of deceleration p.motionX /= 0.91F; p.motionZ /= 0.91F; p.motionY /= 0.9800000190734863D; // Do freefall motion if (!p.capabilities.isCreativeMode) { double dx = p.motionX - this.pPrevMotionX; double dy = p.motionY - this.pPrevMotionY; double dz = p.motionZ - this.pPrevMotionZ; double dyaw = p.rotationYaw - p.prevRotationYaw; p.rotationYaw -= dyaw * 0.8D; // if (p.capabilities.isFlying) /// Undo whatever vanilla tried to do to our y motion p.motionY -= dy; p.motionX -= dx; p.motionZ -= dz; if (p.movementInput.moveForward != 0) { p.motionX -= p.movementInput.moveForward * MathHelper.sin(p.rotationYaw / 57.29578F) / 400F; p.motionZ += p.movementInput.moveForward * MathHelper.cos(p.rotationYaw / 57.29578F) / 400F; } if (p.movementInput.sneak) { p.motionY -= 0.0015D; } if (p.movementInput.jump) { p.motionY += 0.0015D; } if (p.motionX > 0.7F) { p.motionX = 0.7F; } if (p.motionX < -0.7F) { p.motionX = -0.7F; } if (p.motionY > 0.7F) { p.motionY = 0.7F; } if (p.motionY < -0.7F) { p.motionY = -0.7F; } if (p.motionZ > 0.7F) { p.motionZ = 0.7F; } if (p.motionZ < -0.7F) { p.motionZ = -0.7F; } } else { if (p.motionX > 1.2F) { p.motionX = 1.2F; } if (p.motionX < -1.2F) { p.motionX = -1.2F; } if (p.motionZ > 1.2F) { p.motionZ = 1.2F; } if (p.motionZ < -1.2F) { p.motionZ = -1.2F; } } // TODO: Think about endless drift? // Player may run out of oxygen - that will kill the player eventually if can't get back to SS // Maybe player needs a 'suicide' button if floating helplessly in space and with no tether // Could auto-kill + respawn the player if floats too far away (config option whether to lose // items or not) // But we want players to be able to enjoy the view of the spinning space station from the // outside // Arm and leg movements could start tumbling the player? } else { if (p.movementInput.jump) { if (p.onGround) { p.motionY += 0.15D; } else { p.motionY += 0.01D; } } else if (p.movementInput.sneak) { if (!p.onGround) { p.motionY -= 0.01D; } } } // Artificial gravity if (doGravity) { int quadrant = 0; double xd = p.posX - this.spinCentreX; double zd = p.posZ - this.spinCentreZ; double accel = Math.sqrt(xd * xd + zd * zd) * this.angularVelocityRadians * this.angularVelocityRadians * 4D; if (xd < 0) { if (xd < -Math.abs(zd)) { quadrant = 2; } else { quadrant = zd < 0 ? 3 : 1; } } else if (xd > Math.abs(zd)) { quadrant = 0; } else { quadrant = zd < 0 ? 3 : 1; } switch (quadrant) { case 0: p.motionX += accel; break; case 1: p.motionZ += accel; break; case 2: p.motionX -= accel; break; case 3: default: p.motionZ -= accel; } } p.inFreefall = freefall; p.inFreefallFirstCheck = true; this.pPrevMotionX = p.motionX; this.pPrevMotionY = p.motionY; this.pPrevMotionZ = p.motionZ; }
/** * Spawn a digging particle effect in the world, this is a wrapper around * EffectRenderer.addBlockHitEffects to allow the block more control over the particles. Useful * when you have entirely different texture sheets for different sides/locations in the world. * * @param world The current world * @param target The target the player is looking at {x/y/z/side/sub} * @param effectRenderer A reference to the current effect renderer. * @return True to prevent vanilla digging particles form spawning. */ @SideOnly(Side.CLIENT) @Override public boolean addBlockHitEffects( World worldObj, MovingObjectPosition target, EffectRenderer effectRenderer) { int x = target.blockX; int y = target.blockY; int z = target.blockZ; Pipe pipe = getPipe(worldObj, x, y, z); if (pipe == null) return false; Icon icon = pipe.getIconProvider().getIcon(pipe.getIconIndexForItem()); int sideHit = target.sideHit; Block block = BuildCraftTransport.genericPipeBlock; float b = 0.1F; double px = x + rand.nextDouble() * (block.getBlockBoundsMaxX() - block.getBlockBoundsMinX() - (b * 2.0F)) + b + block.getBlockBoundsMinX(); double py = y + rand.nextDouble() * (block.getBlockBoundsMaxY() - block.getBlockBoundsMinY() - (b * 2.0F)) + b + block.getBlockBoundsMinY(); double pz = z + rand.nextDouble() * (block.getBlockBoundsMaxZ() - block.getBlockBoundsMinZ() - (b * 2.0F)) + b + block.getBlockBoundsMinZ(); if (sideHit == 0) { py = (double) y + block.getBlockBoundsMinY() - (double) b; } if (sideHit == 1) { py = (double) y + block.getBlockBoundsMaxY() + (double) b; } if (sideHit == 2) { pz = (double) z + block.getBlockBoundsMinZ() - (double) b; } if (sideHit == 3) { pz = (double) z + block.getBlockBoundsMaxZ() + (double) b; } if (sideHit == 4) { px = (double) x + block.getBlockBoundsMinX() - (double) b; } if (sideHit == 5) { px = (double) x + block.getBlockBoundsMaxX() + (double) b; } EntityDiggingFX fx = new EntityDiggingFX( worldObj, px, py, pz, 0.0D, 0.0D, 0.0D, block, sideHit, worldObj.getBlockMetadata(x, y, z)); fx.func_110125_a(icon); effectRenderer.addEffect( fx.applyColourMultiplier(x, y, z).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F)); return true; }