diff --git a/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java b/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java index bbb54060..97a37c71 100644 --- a/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java +++ b/src/main/java/cr0s/warpdrive/block/building/TileEntityShipScanner.java @@ -4,6 +4,7 @@ import cr0s.warpdrive.Commons; import cr0s.warpdrive.WarpDrive; import cr0s.warpdrive.api.ISequencerCallbacks; import cr0s.warpdrive.block.TileEntityAbstractInterfaced; +import cr0s.warpdrive.block.movement.BlockShipCore; import cr0s.warpdrive.block.movement.TileEntityShipCore; import cr0s.warpdrive.config.Dictionary; import cr0s.warpdrive.config.WarpDriveConfig; @@ -42,6 +43,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.MathHelper; +import net.minecraft.world.World; import cpw.mods.fml.common.Optional; @@ -419,7 +421,7 @@ public class TileEntityShipScanner extends TileEntityAbstractInterfaced implemen final double distance = MathHelper.sqrt_double(dX * dX + dY * dY + dZ * dZ); if (distance > WarpDriveConfig.SS_MAX_DEPLOY_RADIUS_BLOCKS) { - reason.append(String.format("Cannot deploy ship more than %d blocks away from scanner.", WarpDriveConfig.SS_MAX_DEPLOY_RADIUS_BLOCKS)); + reason.append(String.format("§cCannot deploy ship more than %d blocks away from scanner.", WarpDriveConfig.SS_MAX_DEPLOY_RADIUS_BLOCKS)); return 5; } @@ -437,14 +439,11 @@ public class TileEntityShipScanner extends TileEntityAbstractInterfaced implemen Math.max(targetLocation1.posZ, targetLocation2.posZ) + 1); if (isForced) { - if (!worldObj.isAirBlock(targetX, targetY, targetZ)) { - worldObj.newExplosion(null, targetX, targetY, targetZ, 1, false, false); + if (!isShipCoreClear(worldObj, targetX, targetY, targetZ, playerName, reason)) { if (WarpDriveConfig.LOGGING_BUILDING) { WarpDrive.logger.info(String.format("Deployment collision detected at (%d %d %d)", targetX, targetY, targetZ)); } - reason.append(String.format("Deployment area occupied with existing ship.\nCan't deploy new ship at (%d %d %d)", - targetX, targetY, targetZ)); return 2; } @@ -478,7 +477,7 @@ public class TileEntityShipScanner extends TileEntityAbstractInterfaced implemen } } if (occupiedBlockCount > 0) { - reason.append(String.format("Deployment area occupied with %d blocks. Can't deploy ship.", occupiedBlockCount)); + reason.append(String.format("§cDeployment area occupied with %d blocks. Can't deploy ship.", occupiedBlockCount)); return 2; } } @@ -493,6 +492,60 @@ public class TileEntityShipScanner extends TileEntityAbstractInterfaced implemen return 3; } + private static boolean isShipCoreClear(final World world, final int x, final int y, final int z, + final String nameRequestingPlayer, final StringBuilder reason) { + final Block block = world.getBlock(x, y, z); + if (block.isAir(world, x, y, z)) { + return true; + } + + if (!(block instanceof BlockShipCore)) { + world.newExplosion(null, x, y, z, 1, false, false); + reason.append(String.format("§cDeployment area occupied by %s.\nCan't deploy new ship at (%d %d %d)", + block.getLocalizedName(), + x, y, z)); + return false; + } + + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (!(tileEntity instanceof TileEntityShipCore)) { + reason.append(String.format("§cDeployment area occupied with invalid tile entity %s.\nContact an admin for help at (%d %d %d)", + block, x, y, z)); + WarpDrive.logger.error(reason.toString()); + world.newExplosion(null, x, y, z, 1, false, false); + return false; + } + + final TileEntityShipCore tileEntityShipCore = (TileEntityShipCore) tileEntity; + final String namePlayersAboard = tileEntityShipCore.getAllPlayersOnShip(); + if (!namePlayersAboard.isEmpty()) { + reason.append(String.format("§cDeployment area occupied by active crew %s.\n§6Please wait or use another deployment spot", + namePlayersAboard)); + return false; + } + + if (tileEntityShipCore.isBooting()) { + reason.append("§cDeployment area is busy.\n§6Please try again in a few seconds."); + return false; + } + + final String nameOnlineCrew = tileEntityShipCore.getFirstOnlineCrew(); + if (nameOnlineCrew == null || nameOnlineCrew.isEmpty()) { + return true; + } + + if (nameOnlineCrew.equals(nameRequestingPlayer)) { + reason.append(String.format("§cDeployment area occupied by your ship, captain %s!\n§2Come back inside and use the computer to jump away!", + nameOnlineCrew)); + return false; + } + + reason.append(String.format("§cDeployment area occupied with ship owned by %s.\n§6Contact that player or use another deployment spot", + nameOnlineCrew)); + return false; + + } + @Override public void readFromNBT(final NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java index 9ea3c0e8..83564f61 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipCore.java @@ -126,7 +126,13 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta } return; } + TileEntityShipController tileEntityShipController = tileEntityShipControllerWeakReference == null ? null : tileEntityShipControllerWeakReference.get(); + if ( tileEntityShipController != null + && tileEntityShipController.isInvalid() ) { + tileEntityShipControllerWeakReference = null; + tileEntityShipController = null; + } // Always cooldown if (cooldownTime_ticks > 0) { @@ -180,6 +186,9 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta WarpDrive.starMap.updateInRegistry(this); final TileEntityShipController tileEntityShipControllerNew = findControllerBlock(); + if (tileEntityShipControllerNew == null) { + tileEntityShipControllerWeakReference = null; + } if (tileEntityShipControllerNew != tileEntityShipController) { tileEntityShipController = tileEntityShipControllerNew; tileEntityShipControllerWeakReference = new WeakReference<>(tileEntityShipController); @@ -403,7 +412,9 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta return false; } final TileEntityShipController tileEntityShipController = tileEntityShipControllerWeakReference.get(); - return tileEntityShipController != null && tileEntityShipController.getCommand() == EnumShipControllerCommand.OFFLINE; + return tileEntityShipController != null + && !tileEntityShipController.isInvalid() + && tileEntityShipController.getCommand() == EnumShipControllerCommand.OFFLINE; } protected boolean isAttached(final TileEntityShipController tileEntityShipControllerExpected) { @@ -448,6 +459,54 @@ public class TileEntityShipCore extends TileEntityAbstractEnergy implements ISta return stringBuilderResult.toString(); } + public boolean isBooting() { + if (bootTicks > 0) { + return true; + } + + if (tileEntityShipControllerWeakReference == null) {// not attached + return false; + } + + final TileEntityShipController tileEntityShipController = tileEntityShipControllerWeakReference.get(); + if ( tileEntityShipController == null + || tileEntityShipController.isInvalid() ) {// we're desync + // force a refresh + registryUpdateTicks = 0; + return true; + } + + return false; + } + + public String getFirstOnlineCrew() { + if (tileEntityShipControllerWeakReference == null) {// not attached + return null; + } + + final TileEntityShipController tileEntityShipController = tileEntityShipControllerWeakReference.get(); + if ( tileEntityShipController == null + || tileEntityShipController.isInvalid() ) {// we're desync + // force a refresh + registryUpdateTicks = 0; + return "-busy-"; + } + + if (tileEntityShipController.players == null || tileEntityShipController.players.isEmpty()) {// no crew defined + return null; + } + + for (final String namePlayer : tileEntityShipController.players) { + final EntityPlayer entityPlayer = Commons.getOnlinePlayerByName(namePlayer); + if (entityPlayer != null) {// crew member is online + return namePlayer; + } + } + + // all cleared + return null; + } + private void updateIsolationState() { // Search block in cube around core final int xMin = xCoord - WarpDriveConfig.RADAR_MAX_ISOLATION_RANGE; diff --git a/src/main/java/cr0s/warpdrive/event/DeploySequencer.java b/src/main/java/cr0s/warpdrive/event/DeploySequencer.java index 3d6e344e..1a65efbb 100644 --- a/src/main/java/cr0s/warpdrive/event/DeploySequencer.java +++ b/src/main/java/cr0s/warpdrive/event/DeploySequencer.java @@ -52,7 +52,7 @@ public class DeploySequencer extends JumpSequencer { // Warn owner if deployment done but wait next tick for teleportation final EntityPlayerMP entityPlayerMP = Commons.getOnlinePlayerByName(playerName); if (entityPlayerMP != null) { - Commons.addChatMessage(entityPlayerMP, "Ship complete. Teleporting captain to the main deck"); + Commons.addChatMessage(entityPlayerMP, "Ship deployed. Teleporting captain to the main deck..."); } } }