@Override public void updateEntity() { super.updateEntity(); if (FMLCommonHandler.instance().getEffectiveSide().isClient()) return; if (++searchTicks > 20) { shipCore = searchShipCore(); searchTicks = 0; } // Warp core is not found if (!isDeploying && shipCore == null) { setActive(false); // disable scanner return; } if (!isActive) { // inactive if (++laserTicks > 20) { PacketHandler.sendBeamPacket( worldObj, new Vector3(this).translate(0.5D), new Vector3(shipCore.xCoord, shipCore.yCoord, shipCore.zCoord).translate(0.5D), 0f, 1f, 0f, 40, 0, 100); laserTicks = 0; } } else if (!isDeploying) { // active and scanning if (++laserTicks > 5) { laserTicks = 0; for (int i = 0; i < shipCore.maxX - shipCore.minX; i++) { int x = shipCore.minX + i; int randomZ = shipCore.minZ + worldObj.rand.nextInt(shipCore.maxZ - shipCore.minZ); worldObj.playSoundEffect( xCoord + 0.5f, yCoord, zCoord + 0.5f, "warpdrive:lowlaser", 4F, 1F); float r = 0.0f, g = 0.0f, b = 0.0f; switch (worldObj.rand.nextInt(6)) { case 0: r = 1.0f; g = b = 0; break; case 1: r = b = 0; g = 1.0f; break; case 2: r = g = 0; b = 1.0f; break; case 3: r = b = 0.5f; g = 0; break; case 4: r = g = 1.0f; b = 0; break; case 5: r = 1.0f; b = 0.5f; g = 0f; break; default: break; } PacketHandler.sendBeamPacket( worldObj, new Vector3(this).translate(0.5D), new Vector3(x, shipCore.maxY, randomZ).translate(0.5D), r, g, b, 15, 0, 100); } } if (++scanTicks > 20 * (1 + shipCore.shipMass / 10)) { setActive(false); // disable scanner scanTicks = 0; } } else { // active and deploying if (++deployDelayTicks < 20) return; deployDelayTicks = 0; int blocks = Math.min(WarpDriveConfig.G_BLOCKS_PER_TICK, blocksToDeployCount - currentDeployIndex); if (blocks == 0) { isDeploying = false; setActive(false); // disable scanner return; } for (int index = 0; index < blocks; index++) { if (currentDeployIndex >= blocksToDeployCount) { isDeploying = false; setActive(false); // disable scanner break; } // Deploy single block JumpBlock jb = blocksToDeploy[currentDeployIndex]; if (jb != null && !WarpDriveConfig.BLOCKS_ANCHOR.contains(jb.block)) { Block blockAtTarget = worldObj.getBlock(targetX + jb.x, targetY + jb.y, targetZ + jb.z); if (blockAtTarget == Blocks.air || WarpDriveConfig.BLOCKS_EXPANDABLE.contains(blockAtTarget)) { jb.deploy(worldObj, targetX, targetY, targetZ); if (worldObj.rand.nextInt(100) <= 10) { worldObj.playSoundEffect( xCoord + 0.5f, yCoord, zCoord + 0.5f, "warpdrive:lowlaser", 4F, 1F); PacketHandler.sendBeamPacket( worldObj, new Vector3(this).translate(0.5D), new Vector3(targetX + jb.x, targetY + jb.y, targetZ + jb.z).translate(0.5D), 0f, 1f, 0f, 15, 0, 100); } } } currentDeployIndex++; } } }
// Returns error code and reason string private int deployShip( String fileName, int offsetX, int offsetY, int offsetZ, StringBuilder reason) { // Load schematic NBTTagCompound schematic = readNBTFromFile(WarpDriveConfig.G_SCHEMALOCATION + "/" + fileName); if (schematic == null) { reason.append("Schematic not found or unknow error reading it."); return -1; } // Compute geometry short width = schematic.getShort("Width"); short height = schematic.getShort("Height"); short length = schematic.getShort("Length"); targetX = xCoord + offsetX; targetY = yCoord + offsetY; targetZ = zCoord + offsetZ; blocksToDeployCount = width * height * length; // Validate context { // Check distance double dX = xCoord - targetX; double dY = yCoord - targetY; double dZ = zCoord - targetZ; double distance = MathHelper.sqrt_double(dX * dX + dY * dY + dZ * dZ); if (distance > WarpDriveConfig.SS_MAX_DEPLOY_RADIUS_BLOCKS) { reason.append("Cannot deploy ship so far away from scanner."); return 5; } // Consume energy if (!consumeEnergy(getDeploymentEnergyCost(blocksToDeployCount), false)) { reason.append( "Insufficient energy (" + getDeploymentEnergyCost(blocksToDeployCount) + " required)"); return 1; } // Check specified area for occupation by blocks // If specified area occupied, break deploying with error message int occupiedBlockCount = 0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { if (!worldObj.isAirBlock(targetX + x, targetY + y, targetZ + z)) occupiedBlockCount++; } } } if (occupiedBlockCount > 0) { reason.append( "Deploying area occupied with " + occupiedBlockCount + " blocks. Can't deploy ship."); return 2; } } // Set deployment variables blocksToDeploy = new JumpBlock[blocksToDeployCount]; isDeploying = true; currentDeployIndex = 0; // Read blocks and TileEntities from NBT to internal storage array NBTTagList localBlocks = (NBTTagList) schematic.getTag("Blocks"); byte localMetadata[] = schematic.getByteArray("Data"); // Load Tile Entities NBTTagCompound[] tileEntities = new NBTTagCompound[blocksToDeployCount]; NBTTagList tileEntitiesList = schematic.getTagList( "TileEntities", new NBTTagByteArray(new byte[0]).getId()); // TODO: 0 is not correct for (int i = 0; i < tileEntitiesList.tagCount(); i++) { NBTTagCompound teTag = tileEntitiesList.getCompoundTagAt(i); int teX = teTag.getInteger("x"); int teY = teTag.getInteger("y"); int teZ = teTag.getInteger("z"); tileEntities[teX + (teY * length + teZ) * width] = teTag; } // Create list of blocks to deploy for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { int index = x + (y * length + z) * width; JumpBlock jb = new JumpBlock(); jb.x = x; jb.y = y; jb.z = z; jb.block = Block.getBlockFromName(localBlocks.getStringTagAt(index)); jb.blockMeta = (localMetadata[index]) & 0xFF; jb.blockNBT = tileEntities[index]; if (jb.block != null) { if (WarpDriveConfig.LOGGING_BUILDING) { if (tileEntities[index] == null) { WarpDrive.logger.info( "[ShipScanner] Adding block to deploy: " + jb.block.getUnlocalizedName() + " (no tile entity)"); } else { WarpDrive.logger.info( "[ShipScanner] Adding block to deploy: " + jb.block.getUnlocalizedName() + " with tile entity " + tileEntities[index].getString("id")); } } blocksToDeploy[index] = jb; } else { jb = null; blocksToDeploy[index] = jb; } } } } setActive(true); reason.append("Ship deploying..."); return 3; }