mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-14 09:46:53 -04:00
Added ability to copy lines from screens using the analyzer (shift-rightclicking the line with the analyzer), then paste it on a screen by simply rightclicking it with the analyzer. Closes #644.
This commit is contained in:
parent
16170e31ee
commit
f69250b565
@ -110,6 +110,15 @@ object PacketSender {
|
|||||||
pb.sendToServer()
|
pb.sendToServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sendCopyToAnalyzer(address: String, line: Int): Unit = {
|
||||||
|
val pb = new SimplePacketBuilder(PacketType.CopyToAnalyzer)
|
||||||
|
|
||||||
|
pb.writeUTF(address)
|
||||||
|
pb.writeInt(line)
|
||||||
|
|
||||||
|
pb.sendToServer()
|
||||||
|
}
|
||||||
|
|
||||||
def sendMultiPlace() {
|
def sendMultiPlace() {
|
||||||
val pb = new SimplePacketBuilder(PacketType.MultiPartPlace)
|
val pb = new SimplePacketBuilder(PacketType.MultiPartPlace)
|
||||||
pb.sendToServer()
|
pb.sendToServer()
|
||||||
|
@ -52,6 +52,7 @@ object PacketType extends Enumeration {
|
|||||||
|
|
||||||
// Client -> Server
|
// Client -> Server
|
||||||
ComputerPower,
|
ComputerPower,
|
||||||
|
CopyToAnalyzer,
|
||||||
DronePower,
|
DronePower,
|
||||||
KeyDown,
|
KeyDown,
|
||||||
KeyUp,
|
KeyUp,
|
||||||
|
@ -6,10 +6,12 @@ import cpw.mods.fml.relauncher.Side
|
|||||||
import cpw.mods.fml.relauncher.SideOnly
|
import cpw.mods.fml.relauncher.SideOnly
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
|
import li.cil.oc.api
|
||||||
import li.cil.oc.common.GuiType
|
import li.cil.oc.common.GuiType
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.integration.util.Wrench
|
import li.cil.oc.integration.util.Wrench
|
||||||
import li.cil.oc.util._
|
import li.cil.oc.util._
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.texture.IIconRegister
|
import net.minecraft.client.renderer.texture.IIconRegister
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.EntityLivingBase
|
import net.minecraft.entity.EntityLivingBase
|
||||||
@ -332,6 +334,7 @@ class Screen(val tier: Int) extends RedstoneAware {
|
|||||||
def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
||||||
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) = {
|
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) = {
|
||||||
if (Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z)) && getValidRotations(world, x, y, z).contains(side) && !force) false
|
if (Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z)) && getValidRotations(world, x, y, z).contains(side) && !force) false
|
||||||
|
else if (api.Items.get(player.getHeldItem) == api.Items.get("analyzer")) false
|
||||||
else world.getTileEntity(x, y, z) match {
|
else world.getTileEntity(x, y, z) match {
|
||||||
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.invertTouchMode) =>
|
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.invertTouchMode) =>
|
||||||
// Yep, this GUI is actually purely client side. We could skip this
|
// Yep, this GUI is actually purely client side. We could skip this
|
||||||
@ -342,7 +345,10 @@ class Screen(val tier: Int) extends RedstoneAware {
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
case screen: tileentity.Screen if screen.tier > 0 && side == screen.facing =>
|
case screen: tileentity.Screen if screen.tier > 0 && side == screen.facing =>
|
||||||
screen.click(player, hitX, hitY, hitZ)
|
if (world.isRemote && player == Minecraft.getMinecraft.thePlayer) {
|
||||||
|
screen.click(hitX, hitY, hitZ)
|
||||||
|
}
|
||||||
|
else true
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,6 +429,10 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
|||||||
override def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer) =
|
override def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer) =
|
||||||
mouseScroll(x, y, delta, player)
|
mouseScroll(x, y, delta, player)
|
||||||
|
|
||||||
|
def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = {
|
||||||
|
proxy.copyToAnalyzer(line, player)
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def onConnect(node: Node) {
|
override def onConnect(node: Node) {
|
||||||
@ -602,6 +606,8 @@ object TextBuffer {
|
|||||||
def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit
|
def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit
|
||||||
|
|
||||||
def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit
|
def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit
|
||||||
|
|
||||||
|
def copyToAnalyzer(line: Int, player: EntityPlayer): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClientProxy(val owner: TextBuffer) extends Proxy {
|
class ClientProxy(val owner: TextBuffer) extends Proxy {
|
||||||
@ -686,6 +692,10 @@ object TextBuffer {
|
|||||||
ClientPacketSender.sendMouseScroll(nodeAddress, x, y, delta)
|
ClientPacketSender.sendMouseScroll(nodeAddress, x, y, delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = {
|
||||||
|
ClientPacketSender.sendCopyToAnalyzer(nodeAddress, line)
|
||||||
|
}
|
||||||
|
|
||||||
private lazy val Debugger = api.Items.get("debugger")
|
private lazy val Debugger = api.Items.get("debugger")
|
||||||
|
|
||||||
private def debug(message: String) {
|
private def debug(message: String) {
|
||||||
@ -789,6 +799,27 @@ object TextBuffer {
|
|||||||
sendMouseEvent(player, "scroll", x, y, delta)
|
sendMouseEvent(player, "scroll", x, y, delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = {
|
||||||
|
val stack = player.getHeldItem
|
||||||
|
if (stack != null) {
|
||||||
|
if (!stack.hasTagCompound) {
|
||||||
|
stack.setTagCompound(new NBTTagCompound())
|
||||||
|
}
|
||||||
|
stack.getTagCompound.removeTag(Settings.namespace + "clipboard")
|
||||||
|
|
||||||
|
if (line >= 0 && line < owner.data.height) {
|
||||||
|
val text = new String(owner.data.buffer(line)).trim
|
||||||
|
if (!Strings.isNullOrEmpty(text)) {
|
||||||
|
stack.getTagCompound.setString(Settings.namespace + "clipboard", text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.getTagCompound.hasNoTags) {
|
||||||
|
stack.setTagCompound(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def sendMouseEvent(player: EntityPlayer, name: String, x: Double, y: Double, data: Int) = {
|
private def sendMouseEvent(player: EntityPlayer, name: String, x: Double, y: Double, data: Int) = {
|
||||||
val args = mutable.ArrayBuffer.empty[AnyRef]
|
val args = mutable.ArrayBuffer.empty[AnyRef]
|
||||||
|
|
||||||
|
@ -2,15 +2,18 @@ package li.cil.oc.common.item
|
|||||||
|
|
||||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||||
import li.cil.oc.Localization
|
import li.cil.oc.Localization
|
||||||
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
import li.cil.oc.api.network.Analyzable
|
import li.cil.oc.api.network.Analyzable
|
||||||
import li.cil.oc.api.network._
|
import li.cil.oc.api.network._
|
||||||
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.server.PacketSender
|
import li.cil.oc.server.PacketSender
|
||||||
import li.cil.oc.util.BlockPosition
|
import li.cil.oc.util.BlockPosition
|
||||||
import li.cil.oc.util.ExtendedWorld._
|
import li.cil.oc.util.ExtendedWorld._
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.entity.player.EntityPlayerMP
|
import net.minecraft.entity.player.EntityPlayerMP
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
import net.minecraftforge.common.util.ForgeDirection
|
import net.minecraftforge.common.util.ForgeDirection
|
||||||
import net.minecraftforge.event.entity.player.EntityInteractEvent
|
import net.minecraftforge.event.entity.player.EntityInteractEvent
|
||||||
|
|
||||||
@ -79,7 +82,31 @@ object Analyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Analyzer(val parent: Delegator) extends Delegate {
|
class Analyzer(val parent: Delegator) extends Delegate {
|
||||||
|
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = {
|
||||||
|
if (player.isSneaking && stack.hasTagCompound) {
|
||||||
|
stack.getTagCompound.removeTag(Settings.namespace + "clipboard")
|
||||||
|
if (stack.getTagCompound.hasNoTags) {
|
||||||
|
stack.setTagCompound(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onItemRightClick(stack, world, player)
|
||||||
|
}
|
||||||
|
|
||||||
override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
|
override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||||
Analyzer.analyze(position.world.get.getTileEntity(position), player, side, hitX, hitY, hitZ)
|
val world = player.getEntityWorld
|
||||||
|
world.getTileEntity(position) match {
|
||||||
|
case screen: tileentity.Screen if ForgeDirection.getOrientation(side) == screen.facing =>
|
||||||
|
if (player.isSneaking) {
|
||||||
|
screen.copyToAnalyzer(hitX, hitY, hitZ)
|
||||||
|
}
|
||||||
|
else if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "clipboard")) {
|
||||||
|
if (!world.isRemote) {
|
||||||
|
screen.origin.buffer.clipboard(stack.getTagCompound.getString(Settings.namespace + "clipboard"), player)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else false
|
||||||
|
case _ => Analyzer.analyze(position.world.get.getTileEntity(position), player, side, hitX, hitY, hitZ)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly
|
|||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api.network.Analyzable
|
import li.cil.oc.api.network.Analyzable
|
||||||
import li.cil.oc.api.network._
|
import li.cil.oc.api.network._
|
||||||
|
import li.cil.oc.common.component.TextBuffer
|
||||||
import li.cil.oc.util.Color
|
import li.cil.oc.util.Color
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
@ -93,7 +94,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
|||||||
invertTouchMode = false
|
invertTouchMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
def click(player: EntityPlayer, hitX: Double, hitY: Double, hitZ: Double): Boolean = {
|
def toScreenCoordinates(hitX: Double, hitY: Double, hitZ: Double): (Boolean, Option[(Double, Double)]) = {
|
||||||
// Compute absolute position of the click on the face, measured in blocks.
|
// Compute absolute position of the click on the face, measured in blocks.
|
||||||
def dot(f: ForgeDirection) = f.offsetX * hitX + f.offsetY * hitY + f.offsetZ * hitZ
|
def dot(f: ForgeDirection) = f.offsetX * hitX + f.offsetY * hitY + f.offsetZ * hitZ
|
||||||
val (hx, hy) = (dot(toGlobal(ForgeDirection.EAST)), dot(toGlobal(ForgeDirection.UP)))
|
val (hx, hy) = (dot(toGlobal(ForgeDirection.EAST)), dot(toGlobal(ForgeDirection.UP)))
|
||||||
@ -105,9 +106,9 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
|||||||
// Get the relative position in the *display area* of the face.
|
// Get the relative position in the *display area* of the face.
|
||||||
val border = 2.25 / 16.0
|
val border = 2.25 / 16.0
|
||||||
if (ax <= border || ay <= border || ax >= width - border || ay >= height - border) {
|
if (ax <= border || ay <= border || ax >= width - border || ay >= height - border) {
|
||||||
return false
|
return (false, None)
|
||||||
}
|
}
|
||||||
if (!world.isRemote) return true
|
if (!world.isRemote) return (true, None)
|
||||||
|
|
||||||
val (iw, ih) = (width - border * 2, height - border * 2)
|
val (iw, ih) = (width - border * 2, height - border * 2)
|
||||||
val (rx, ry) = ((ax - border) / iw, (ay - border) / ih)
|
val (rx, ry) = ((ax - border) / iw, (ay - border) / ih)
|
||||||
@ -119,27 +120,43 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
|||||||
val (brx, bry) = if (bpw > bph) {
|
val (brx, bry) = if (bpw > bph) {
|
||||||
val rh = bph.toDouble / bpw.toDouble
|
val rh = bph.toDouble / bpw.toDouble
|
||||||
val bry = (ry - (1 - rh) * 0.5) / rh
|
val bry = (ry - (1 - rh) * 0.5) / rh
|
||||||
if (bry <= 0 || bry >= 1) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
(rx, bry)
|
(rx, bry)
|
||||||
}
|
}
|
||||||
else if (bph > bpw) {
|
else if (bph > bpw) {
|
||||||
val rw = bpw.toDouble / bph.toDouble
|
val rw = bpw.toDouble / bph.toDouble
|
||||||
val brx = (rx - (1 - rw) * 0.5) / rw
|
val brx = (rx - (1 - rw) * 0.5) / rw
|
||||||
if (brx <= 0 || brx >= 1) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
(brx, ry)
|
(brx, ry)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(rx, ry)
|
(rx, ry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to absolute coordinates and send the packet to the server.
|
val inBounds = bry >= 0 && bry <= 1 && brx >= 0 || brx <= 1
|
||||||
origin.buffer.mouseDown(brx * bw, bry * bh, 0, null)
|
(inBounds, Some((brx * bw, bry * bh)))
|
||||||
|
}
|
||||||
|
|
||||||
true
|
def copyToAnalyzer(hitX: Double, hitY: Double, hitZ: Double): Boolean = {
|
||||||
|
val (inBounds, coordinates) = toScreenCoordinates(hitX, hitY, hitZ)
|
||||||
|
coordinates match {
|
||||||
|
case Some((x, y)) => origin.buffer match {
|
||||||
|
case buffer: TextBuffer =>
|
||||||
|
buffer.copyToAnalyzer(y.toInt, null)
|
||||||
|
true
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
case _ => inBounds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def click(hitX: Double, hitY: Double, hitZ: Double): Boolean = {
|
||||||
|
val (inBounds, coordinates) = toScreenCoordinates(hitX, hitY, hitZ)
|
||||||
|
coordinates match {
|
||||||
|
case Some((x, y)) =>
|
||||||
|
// Send the packet to the server (manually, for accuracy).
|
||||||
|
origin.buffer.mouseDown(x, y, 0, null)
|
||||||
|
true
|
||||||
|
case _ => inBounds
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def walk(entity: Entity) {
|
def walk(entity: Entity) {
|
||||||
@ -236,7 +253,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
|||||||
hitXInner && !hitYInner && hitZInner ||
|
hitXInner && !hitYInner && hitZInner ||
|
||||||
!hitXInner && hitYInner && hitZInner) {
|
!hitXInner && hitYInner && hitZInner) {
|
||||||
arrow.shootingEntity match {
|
arrow.shootingEntity match {
|
||||||
case player: EntityPlayer if player == Minecraft.getMinecraft.thePlayer => click(player, hitX, hitY, hitZ)
|
case player: EntityPlayer if player == Minecraft.getMinecraft.thePlayer => click(hitX, hitY, hitZ)
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
override def dispatch(p: PacketParser) {
|
override def dispatch(p: PacketParser) {
|
||||||
p.packetType match {
|
p.packetType match {
|
||||||
case PacketType.ComputerPower => onComputerPower(p)
|
case PacketType.ComputerPower => onComputerPower(p)
|
||||||
|
case PacketType.CopyToAnalyzer => onCopyToAnalyzer(p)
|
||||||
case PacketType.DronePower => onDronePower(p)
|
case PacketType.DronePower => onDronePower(p)
|
||||||
case PacketType.KeyDown => onKeyDown(p)
|
case PacketType.KeyDown => onKeyDown(p)
|
||||||
case PacketType.KeyUp => onKeyUp(p)
|
case PacketType.KeyUp => onKeyUp(p)
|
||||||
@ -67,6 +68,13 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def onCopyToAnalyzer(p: PacketParser) {
|
||||||
|
ComponentTracker.get(p.player.worldObj, p.readUTF()) match {
|
||||||
|
case Some(buffer: TextBuffer) => buffer.copyToAnalyzer(p.readInt(), p.player.asInstanceOf[EntityPlayer])
|
||||||
|
case _ => // Invalid Packet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def onDronePower(p: PacketParser) =
|
def onDronePower(p: PacketParser) =
|
||||||
p.readEntity[Drone]() match {
|
p.readEntity[Drone]() match {
|
||||||
case Some(drone) => p.player match {
|
case Some(drone) => p.player match {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user