diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java index 31f42e4e9..67acc879a 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java @@ -46,12 +46,19 @@ public class TileTurtle extends TileComputerBase public static final int INVENTORY_HEIGHT = 4; // Members - + + enum MoveState + { + NOT_MOVED, + IN_PROGRESS, + MOVED + } + private ItemStack[] m_inventory; private ItemStack[] m_previousInventory; private boolean m_inventoryChanged; private TurtleBrain m_brain; - private boolean m_moved; + private MoveState m_moveState; public TileTurtle() { @@ -59,12 +66,12 @@ public class TileTurtle extends TileComputerBase m_previousInventory = new ItemStack[ getSizeInventory() ]; m_inventoryChanged = false; m_brain = createBrain(); - m_moved = false; + m_moveState = MoveState.NOT_MOVED; } public boolean hasMoved() { - return m_moved; + return m_moveState == MoveState.MOVED; } protected TurtleBrain createBrain() @@ -276,6 +283,41 @@ public class TileTurtle extends TileComputerBase } } + @Override + public void onNeighbourChange() + { + if ( m_moveState == MoveState.NOT_MOVED ) + { + super.onNeighbourChange(); + } + } + + @Override + public void onNeighbourTileEntityChange(BlockPos neighbour) + { + if ( m_moveState == MoveState.NOT_MOVED ) + { + super.onNeighbourTileEntityChange( neighbour ); + } + } + + public void notifyMoveStart() + { + if (m_moveState == MoveState.NOT_MOVED) + { + m_moveState = MoveState.IN_PROGRESS; + } + } + + public void notifyMoveEnd() + { + // MoveState.MOVED is final + if (m_moveState == MoveState.IN_PROGRESS) + { + m_moveState = MoveState.NOT_MOVED; + } + } + @Override public void readFromNBT( NBTTagCompound nbttagcompound ) { @@ -401,7 +443,7 @@ public class TileTurtle extends TileComputerBase } // IInventory - + @Override public int getSizeInventory() { @@ -431,7 +473,7 @@ public class TileTurtle extends TileComputerBase return result; } } - + @Override public ItemStack decrStackSize( int slot, int count ) { @@ -447,13 +489,13 @@ public class TileTurtle extends TileComputerBase { return null; } - + if( stack.stackSize <= count ) { setInventorySlotContents( slot, null ); return stack; } - + ItemStack part = stack.splitStack( count ); onInventoryDefinitelyChanged(); return part; @@ -496,7 +538,7 @@ public class TileTurtle extends TileComputerBase } } } - + @Override public String getName() { @@ -550,7 +592,7 @@ public class TileTurtle extends TileComputerBase public void openInventory( EntityPlayer player ) { } - + @Override public void closeInventory( EntityPlayer player ) { @@ -561,7 +603,7 @@ public class TileTurtle extends TileComputerBase { return true; } - + @Override public void markDirty() { @@ -664,6 +706,6 @@ public class TileTurtle extends TileComputerBase m_inventoryChanged = copy.m_inventoryChanged; m_brain = copy.m_brain; m_brain.setOwner( this ); - copy.m_moved = true; + copy.m_moveState = MoveState.MOVED; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java index 1c440d06f..737f96868 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java @@ -495,6 +495,7 @@ public class TurtleBrain implements ITurtleAccess // Cache info about the old turtle (so we don't access this after we delete ourselves) World oldWorld = getWorld(); + TileTurtle oldOwner = m_owner; BlockPos oldPos = m_owner.getPos(); Block oldBlock = m_owner.getBlock(); @@ -504,36 +505,51 @@ public class TurtleBrain implements ITurtleAccess return true; } - // Create a new turtle - if( world.isBlockLoaded( pos ) && world.setBlockState( pos, oldBlock.getDefaultState(), 0 ) ) + if ( !world.isBlockLoaded( pos ) ) { - Block block = world.getBlockState( pos ).getBlock(); - if( block == oldBlock ) + return false; + } + + oldOwner.notifyMoveStart(); + + try + { + // Create a new turtle + if( world.setBlockState( pos, oldBlock.getDefaultState(), 0 ) ) { - TileEntity newTile = world.getTileEntity( pos ); - if( newTile != null && newTile instanceof TileTurtle ) + Block block = world.getBlockState( pos ).getBlock(); + if( block == oldBlock ) { - // Copy the old turtle state into the new turtle - TileTurtle newTurtle = (TileTurtle)newTile; - newTurtle.setWorldObj( world ); - newTurtle.setPos( pos ); - newTurtle.transferStateFrom( m_owner ); - newTurtle.createServerComputer().setWorld( world ); - newTurtle.createServerComputer().setPosition( pos ); + TileEntity newTile = world.getTileEntity( pos ); + if( newTile != null && newTile instanceof TileTurtle ) + { + // Copy the old turtle state into the new turtle + TileTurtle newTurtle = (TileTurtle)newTile; + newTurtle.setWorldObj( world ); + newTurtle.setPos( pos ); + newTurtle.transferStateFrom( oldOwner ); + newTurtle.createServerComputer().setWorld( world ); + newTurtle.createServerComputer().setPosition( pos ); - // Remove the old turtle - oldWorld.setBlockToAir( oldPos ); + // Remove the old turtle + oldWorld.setBlockToAir( oldPos ); - // Make sure everybody knows about it - newTurtle.updateBlock(); - newTurtle.updateInput(); - newTurtle.updateOutput(); - return true; + // Make sure everybody knows about it + newTurtle.updateBlock(); + newTurtle.updateInput(); + newTurtle.updateOutput(); + return true; + } } - } - // Something went wrong, remove the newly created turtle - world.setBlockToAir( pos ); + // Something went wrong, remove the newly created turtle + world.setBlockToAir( pos ); + } + } + finally + { + // whatever happens, unblock old turtle in case it's still in world + oldOwner.notifyMoveEnd(); } return false;