diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index 48a69bd33..9a73341a6 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -334,23 +334,6 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern } } - override def setDead() { - super.setDead() - if (!world.isRemote) { - machine.stop() - machine.node.remove() - components.disconnectComponents() - components.saveComponents() - val stack = api.Items.get(Constants.ItemName.Drone).createItemStack(1) - info.storedEnergy = control.node.localBuffer.toInt - info.save(stack) - val entity = new EntityItem(world, posX, posY, posZ, stack) - entity.delayBeforeCanPickup = 15 - world.spawnEntityInWorld(entity) - InventoryUtils.dropAllSlots(BlockPosition(this: Entity), mainInventory) - } - } - override def onUpdate() { super.onUpdate() @@ -488,15 +471,63 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern // ----------------------------------------------------------------------- // + private var isChangingDimension = false + override def travelToDimension(dimension: Int) { - // Store relative target and update after teleportation, because our frame - // of reference most certainly changed (i.e. we'll spawn at different - // coordinates than the ones we started traveling from). - val relativeTarget = Vec3.createVectorHelper(targetX - posX, targetY - posY, targetZ - posZ) - super.travelToDimension(dimension) - targetX = (posX + relativeTarget.xCoord).toFloat - targetY = (posY + relativeTarget.yCoord).toFloat - targetZ = (posZ + relativeTarget.zCoord).toFloat + // Store relative target as target, to allow adding that in our "new self" + // (entities get re-created after changing dimension). + targetX = (targetX - posX).toFloat + targetY = (targetY - posY).toFloat + targetZ = (targetZ - posZ).toFloat + try { + isChangingDimension = true + super.travelToDimension(dimension) + } + finally { + isChangingDimension = false + setDead() // Again, to actually close old machine state after copying it. + } + } + + override def copyDataFrom(entity: Entity, unused: Boolean): Unit = { + super.copyDataFrom(entity, unused) + // Compute relative target based on old position and update, because our + // frame of reference most certainly changed (i.e. we'll spawn at different + // coordinates than the ones we started traveling from, e.g. when porting + // to the nether it'll be oldpos / 8). + entity match { + case drone: Drone => + targetX = (posX + drone.targetX).toFloat + targetY = (posY + drone.targetY).toFloat + targetZ = (posZ + drone.targetZ).toFloat + case _ => + targetX = posX.toFloat + targetY = posY.toFloat + targetZ = posZ.toFloat + } + } + + override def setDead() { + super.setDead() + if (!world.isRemote && !isChangingDimension) { + machine.stop() + machine.node.remove() + components.disconnectComponents() + components.saveComponents() + } + } + + override def kill(): Unit = { + super.kill() + if (!world.isRemote) { + val stack = api.Items.get(Constants.ItemName.Drone).createItemStack(1) + info.storedEnergy = control.node.localBuffer.toInt + info.save(stack) + val entity = new EntityItem(world, posX, posY, posZ, stack) + entity.delayBeforeCanPickup = 15 + world.spawnEntityInWorld(entity) + InventoryUtils.dropAllSlots(BlockPosition(this: Entity), mainInventory) + } } override def getCommandSenderName = Localization.localizeImmediately("entity.oc.Drone.name")