mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 03:05:30 -04:00
remote terminal basic stuff. can be bound and used to control servers. servers simply have a neighbor visible built-in screen and keyboard for which the gui can be opened using the terminal item once bound. still missing a couple of checks.
This commit is contained in:
parent
125cedeadc
commit
0f067e37c4
BIN
assets/opencomputers/textures/items/terminal.png
Normal file
BIN
assets/opencomputers/textures/items/terminal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 306 B |
6
assets/opencomputers/textures/items/terminal.png.mcmeta
Normal file
6
assets/opencomputers/textures/items/terminal.png.mcmeta
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"animation": {
|
||||
"frametime": 10,
|
||||
"frames": [ 0, 1 ]
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
package li.cil.oc.client
|
||||
|
||||
import li.cil.oc.Items
|
||||
import li.cil.oc.common.inventory.ServerInventory
|
||||
import li.cil.oc.common.{GuiHandler => CommonGuiHandler, item, tileentity, GuiType}
|
||||
import li.cil.oc.{Settings, Items}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.world.World
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object GuiHandler extends CommonGuiHandler {
|
||||
override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) =
|
||||
@ -20,7 +21,7 @@ object GuiHandler extends CommonGuiHandler {
|
||||
case rack: tileentity.Rack if id == GuiType.Rack.id =>
|
||||
new gui.Rack(player.inventory, rack)
|
||||
case screen: tileentity.Screen if id == GuiType.Screen.id =>
|
||||
new gui.Screen(screen)
|
||||
new gui.Screen(screen.origin.buffer, screen.tier > 0, () => screen.origin.hasPower)
|
||||
case _ => Items.multi.subItem(player.getCurrentEquippedItem) match {
|
||||
case Some(server: item.Server) if id == GuiType.Server.id =>
|
||||
new gui.Server(player.inventory, new ServerInventory {
|
||||
@ -29,7 +30,27 @@ object GuiHandler extends CommonGuiHandler {
|
||||
override def isUseableByPlayer(player: EntityPlayer) = player == player
|
||||
})
|
||||
case Some(terminal: item.Terminal) if id == GuiType.Terminal.id =>
|
||||
null // TODO
|
||||
val stack = player.getCurrentEquippedItem
|
||||
if (stack.hasTagCompound) {
|
||||
val address = stack.getTagCompound.getString(Settings.namespace + "server")
|
||||
if (address != null && !address.isEmpty) {
|
||||
// Check if bound to server is loaded. TODO optimize this?
|
||||
world.loadedTileEntityList.flatMap {
|
||||
case rack: tileentity.Rack => rack.terminals
|
||||
case _ => Iterable.empty
|
||||
} find (_.rack.isPresent.exists {
|
||||
case Some(value) => value == address
|
||||
case _ => false
|
||||
}) match {
|
||||
case Some(term) =>
|
||||
// TODO check reachability
|
||||
new gui.Screen(term.buffer, true, () => true)
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
else null
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
|
@ -167,44 +167,53 @@ class PacketHandler extends CommonPacketHandler {
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onScreenColorChange(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) =>
|
||||
t.buffer.foreground = p.readInt()
|
||||
t.buffer.background = p.readInt()
|
||||
case _ => // Invalid packet.
|
||||
def onScreenColorChange(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
buffer.foreground = p.readInt()
|
||||
buffer.background = p.readInt()
|
||||
}
|
||||
|
||||
def onScreenCopy(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) =>
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
val tx = p.readInt()
|
||||
val ty = p.readInt()
|
||||
t.buffer.copy(col, row, w, h, tx, ty)
|
||||
case _ => // Invalid packet.
|
||||
def onScreenCopy(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
val tx = p.readInt()
|
||||
val ty = p.readInt()
|
||||
buffer.copy(col, row, w, h, tx, ty)
|
||||
}
|
||||
|
||||
def onScreenDepthChange(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) => t.buffer.depth = PackedColor.Depth(p.readInt())
|
||||
case _ => // Invalid packet.
|
||||
def onScreenDepthChange(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
buffer.depth = PackedColor.Depth(p.readInt())
|
||||
}
|
||||
|
||||
def onScreenFill(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) =>
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
val c = p.readChar()
|
||||
t.buffer.fill(col, row, w, h, c)
|
||||
case _ => // Invalid packet.
|
||||
def onScreenFill(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
val c = p.readChar()
|
||||
buffer.fill(col, row, w, h, c)
|
||||
}
|
||||
|
||||
def onScreenPowerChange(p: PacketParser) =
|
||||
p.readTileEntity[Screen]() match {
|
||||
@ -212,28 +221,37 @@ class PacketHandler extends CommonPacketHandler {
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onScreenResolutionChange(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) =>
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
t.buffer.resolution = (w, h)
|
||||
case _ => // Invalid packet.
|
||||
def onScreenResolutionChange(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val w = p.readInt()
|
||||
val h = p.readInt()
|
||||
buffer.resolution = (w, h)
|
||||
}
|
||||
|
||||
def onScreenSet(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(t) =>
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val s = p.readUTF()
|
||||
t.buffer.set(col, row, s)
|
||||
case _ => // Invalid packet.
|
||||
def onScreenSet(p: PacketParser) {
|
||||
val buffer = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Buffer) => t.buffer
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
val s = p.readUTF()
|
||||
buffer.set(col, row, s)
|
||||
}
|
||||
|
||||
def onServerPresence(p: PacketParser) =
|
||||
p.readTileEntity[Rack]() match {
|
||||
case Some(t) => for (i <- 0 until t.isPresent.length) t.isPresent(i) = p.readBoolean()
|
||||
case Some(t) => for (i <- 0 until t.isPresent.length) {
|
||||
if (p.readBoolean()) {
|
||||
t.isPresent(i) = Some(p.readUTF())
|
||||
}
|
||||
else t.isPresent(i) = None
|
||||
}
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package li.cil.oc.client
|
||||
|
||||
import li.cil.oc.common.PacketBuilder
|
||||
import li.cil.oc.common.PacketType
|
||||
import li.cil.oc.common.component
|
||||
import li.cil.oc.common.tileentity._
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
|
||||
@ -15,61 +16,93 @@ object PacketSender {
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendKeyDown(t: Buffer, char: Char, code: Int) =
|
||||
if (t.hasKeyboard) {
|
||||
val pb = new PacketBuilder(PacketType.KeyDown)
|
||||
def sendKeyDown(b: component.Buffer, char: Char, code: Int) {
|
||||
val pb = new PacketBuilder(PacketType.KeyDown)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeChar(char)
|
||||
pb.writeInt(code)
|
||||
|
||||
pb.sendToServer()
|
||||
b.owner match {
|
||||
case t: Buffer if t.hasKeyboard =>
|
||||
pb.writeTileEntity(t)
|
||||
case t: component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
case _ => return
|
||||
}
|
||||
pb.writeChar(char)
|
||||
pb.writeInt(code)
|
||||
|
||||
def sendKeyUp(t: Buffer, char: Char, code: Int) =
|
||||
if (t.hasKeyboard) {
|
||||
val pb = new PacketBuilder(PacketType.KeyUp)
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeChar(char)
|
||||
pb.writeInt(code)
|
||||
def sendKeyUp(b: component.Buffer, char: Char, code: Int) {
|
||||
val pb = new PacketBuilder(PacketType.KeyUp)
|
||||
|
||||
pb.sendToServer()
|
||||
b.owner match {
|
||||
case t: Buffer if t.hasKeyboard =>
|
||||
pb.writeTileEntity(t)
|
||||
case t: component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
case _ => return
|
||||
}
|
||||
pb.writeChar(char)
|
||||
pb.writeInt(code)
|
||||
|
||||
def sendClipboard(t: Buffer, value: String) =
|
||||
if (value != null && !value.isEmpty && t.hasKeyboard) {
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendClipboard(b: component.Buffer, value: String) {
|
||||
if (value != null && !value.isEmpty) {
|
||||
val pb = new PacketBuilder(PacketType.Clipboard)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
b.owner match {
|
||||
case t: Buffer if t.hasKeyboard =>
|
||||
pb.writeTileEntity(t)
|
||||
case t: component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
case _ => return
|
||||
}
|
||||
pb.writeUTF(value.substring(0, math.min(value.length, 1024)))
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
}
|
||||
|
||||
def sendMouseClick(t: Buffer, x: Int, y: Int, drag: Boolean) =
|
||||
if (t.tier > 0) {
|
||||
val pb = new PacketBuilder(PacketType.MouseClickOrDrag)
|
||||
def sendMouseClick(b: component.Buffer, x: Int, y: Int, drag: Boolean) {
|
||||
val pb = new PacketBuilder(PacketType.MouseClickOrDrag)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeInt(x)
|
||||
pb.writeInt(y)
|
||||
pb.writeBoolean(drag)
|
||||
|
||||
pb.sendToServer()
|
||||
b.owner match {
|
||||
case t: Buffer if t.tier > 0 =>
|
||||
pb.writeTileEntity(t)
|
||||
case t: component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(x)
|
||||
pb.writeInt(y)
|
||||
pb.writeBoolean(drag)
|
||||
|
||||
def sendMouseScroll(t: Buffer, x: Int, y: Int, scroll: Int) =
|
||||
if (t.tier > 0) {
|
||||
val pb = new PacketBuilder(PacketType.MouseScroll)
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeInt(x)
|
||||
pb.writeInt(y)
|
||||
pb.writeByte(scroll)
|
||||
def sendMouseScroll(b: component.Buffer, x: Int, y: Int, scroll: Int) {
|
||||
val pb = new PacketBuilder(PacketType.MouseScroll)
|
||||
|
||||
pb.sendToServer()
|
||||
b.owner match {
|
||||
case t: Buffer if t.tier > 0 =>
|
||||
pb.writeTileEntity(t)
|
||||
case t: component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(x)
|
||||
pb.writeInt(y)
|
||||
pb.writeByte(scroll)
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendServerPower(t: Rack, number: Int, power: Boolean) {
|
||||
val pb = new PacketBuilder(PacketType.ComputerPower)
|
||||
|
@ -43,7 +43,7 @@ trait Buffer extends GuiScreen {
|
||||
super.onGuiClosed()
|
||||
buffer.owner.currentGui = None
|
||||
for ((code, char) <- pressedKeys) {
|
||||
PacketSender.sendKeyUp(buffer.owner, char, code)
|
||||
PacketSender.sendKeyUp(buffer, char, code)
|
||||
}
|
||||
Keyboard.enableRepeatEvents(false)
|
||||
}
|
||||
@ -75,17 +75,17 @@ trait Buffer extends GuiScreen {
|
||||
if (Keyboard.getEventKeyState) {
|
||||
val char = Keyboard.getEventCharacter
|
||||
if (!pressedKeys.contains(code) || !ignoreRepeat(char, code)) {
|
||||
PacketSender.sendKeyDown(buffer.owner, char, code)
|
||||
PacketSender.sendKeyDown(buffer, char, code)
|
||||
pressedKeys += code -> char
|
||||
}
|
||||
}
|
||||
else pressedKeys.remove(code) match {
|
||||
case Some(char) => PacketSender.sendKeyUp(buffer.owner, char, code)
|
||||
case Some(char) => PacketSender.sendKeyUp(buffer, char, code)
|
||||
case _ => // Wasn't pressed while viewing the screen.
|
||||
}
|
||||
|
||||
if (isPasteShortcutPressed && Keyboard.getEventKeyState) {
|
||||
PacketSender.sendClipboard(buffer.owner, GuiScreen.getClipboardString)
|
||||
PacketSender.sendClipboard(buffer, GuiScreen.getClipboardString)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +93,7 @@ trait Buffer extends GuiScreen {
|
||||
override protected def mouseClicked(x: Int, y: Int, button: Int) {
|
||||
super.mouseClicked(x, y, button)
|
||||
if (button == 2) {
|
||||
PacketSender.sendClipboard(buffer.owner, GuiScreen.getClipboardString)
|
||||
PacketSender.sendClipboard(buffer, GuiScreen.getClipboardString)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,12 @@ package li.cil.oc.client.gui
|
||||
import li.cil.oc.client.PacketSender
|
||||
import li.cil.oc.client.renderer.MonospaceFontRenderer
|
||||
import li.cil.oc.client.renderer.gui.BufferRenderer
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.util.RenderState
|
||||
import org.lwjgl.input.Mouse
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
class Screen(val screen: tileentity.Screen) extends Buffer {
|
||||
protected def buffer = screen.origin.buffer
|
||||
|
||||
class Screen(val buffer: common.component.Buffer, val hasMouse: Boolean, val hasPower: () => Boolean) extends Buffer {
|
||||
private val bufferMargin = BufferRenderer.margin + BufferRenderer.innerMargin
|
||||
|
||||
private var x, y = 0
|
||||
@ -27,14 +25,14 @@ class Screen(val screen: tileentity.Screen) extends Buffer {
|
||||
val (bw, bh) = buffer.resolution
|
||||
if (bx > 0 && by > 0 && bx <= bw && by <= bh) {
|
||||
val scroll = math.signum(Mouse.getEventDWheel)
|
||||
PacketSender.sendMouseScroll(buffer.owner, bx, by, scroll)
|
||||
PacketSender.sendMouseScroll(buffer, bx, by, scroll)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override protected def mouseClicked(mouseX: Int, mouseY: Int, button: Int) {
|
||||
super.mouseClicked(mouseX, mouseY, button)
|
||||
if (screen.tier > 0) {
|
||||
if (hasMouse) {
|
||||
if (button == 0) {
|
||||
clickOrDrag(mouseX, mouseY)
|
||||
}
|
||||
@ -43,7 +41,7 @@ class Screen(val screen: tileentity.Screen) extends Buffer {
|
||||
|
||||
protected override def mouseClickMove(mouseX: Int, mouseY: Int, button: Int, timeSinceLast: Long) {
|
||||
super.mouseClickMove(mouseX, mouseY, button, timeSinceLast)
|
||||
if (screen.tier > 0 && timeSinceLast > 10) {
|
||||
if (hasMouse && timeSinceLast > 10) {
|
||||
if (button == 0) {
|
||||
clickOrDrag(mouseX, mouseY)
|
||||
}
|
||||
@ -64,7 +62,7 @@ class Screen(val screen: tileentity.Screen) extends Buffer {
|
||||
val (bw, bh) = buffer.resolution
|
||||
if (bx > 0 && by > 0 && bx <= bw && by <= bh) {
|
||||
if (bx != mx || by != my) {
|
||||
PacketSender.sendMouseClick(buffer.owner, bx, by, mx > 0 && my > 0)
|
||||
PacketSender.sendMouseClick(buffer, bx, by, mx > 0 && my > 0)
|
||||
mx = bx
|
||||
my = by
|
||||
}
|
||||
@ -79,7 +77,7 @@ class Screen(val screen: tileentity.Screen) extends Buffer {
|
||||
def drawBuffer() {
|
||||
GL11.glTranslatef(x, y, 0)
|
||||
BufferRenderer.drawBackground()
|
||||
if (screen.origin.hasPower) {
|
||||
if (hasPower()) {
|
||||
GL11.glTranslatef(bufferMargin, bufferMargin, 0)
|
||||
RenderState.makeItBlend()
|
||||
BufferRenderer.drawText()
|
||||
|
@ -103,7 +103,7 @@ object BlockRenderer extends ISimpleBlockRenderingHandler {
|
||||
val front = rack.facing
|
||||
def renderSide(side: ForgeDirection, lx: Double, lz: Double, hx: Double, hz: Double) {
|
||||
if (side == front) {
|
||||
for (i <- 0 until 4 if rack.isPresent(i)) {
|
||||
for (i <- 0 until 4 if rack.isPresent(i).isDefined) {
|
||||
side match {
|
||||
case ForgeDirection.WEST =>
|
||||
renderer.setRenderBounds(lx, v2 - (i + 1) * fs, lz + u1, u2, v2 - i * fs, hz - u1)
|
||||
|
@ -8,7 +8,7 @@ import li.cil.oc.{api, Settings}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
class Buffer(val owner: tileentity.Buffer) extends api.network.Environment with Persistable {
|
||||
class Buffer(val owner: Buffer.Owner) extends api.network.Environment with Persistable {
|
||||
val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("screen").
|
||||
withConnector().
|
||||
@ -140,3 +140,30 @@ class Buffer(val owner: tileentity.Buffer) extends api.network.Environment with
|
||||
nbt.setNewCompoundTag("buffer", buffer.save)
|
||||
}
|
||||
}
|
||||
|
||||
object Buffer {
|
||||
import li.cil.oc.client.gui
|
||||
|
||||
trait Owner {
|
||||
protected var _currentGui: Option[gui.Buffer] = None
|
||||
|
||||
def currentGui = _currentGui
|
||||
|
||||
def currentGui_=(value: Option[gui.Buffer]) = _currentGui = value
|
||||
|
||||
def tier: Int
|
||||
|
||||
def onScreenColorChange(foreground: Int, background: Int)
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int)
|
||||
|
||||
def onScreenDepthChange(depth: PackedColor.Depth.Value)
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char)
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int)
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String)
|
||||
}
|
||||
|
||||
}
|
94
li/cil/oc/common/component/Terminal.scala
Normal file
94
li/cil/oc/common/component/Terminal.scala
Normal file
@ -0,0 +1,94 @@
|
||||
package li.cil.oc.common.component
|
||||
|
||||
import li.cil.oc.api.network.{Node, Visibility}
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.PackedColor.Depth
|
||||
import li.cil.oc.{Settings, common}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Terminal(val rack: tileentity.Rack, val number: Int) extends Buffer.Owner {
|
||||
val buffer = new common.component.Buffer(this)
|
||||
val keyboard = if (buffer.node != null) {
|
||||
buffer.node.setVisibility(Visibility.Neighbors)
|
||||
new component.Keyboard {
|
||||
override def isUseableByPlayer(p: EntityPlayer) = true // TODO if player has bound terminal
|
||||
}
|
||||
}
|
||||
else null
|
||||
|
||||
def isServer = rack.isServer
|
||||
|
||||
def connect(node: Node) {
|
||||
node.connect(buffer.node)
|
||||
node.connect(keyboard.node)
|
||||
buffer.node.connect(keyboard.node)
|
||||
}
|
||||
|
||||
def tier = 1
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def load(nbt: NBTTagCompound) {
|
||||
buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
|
||||
keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
|
||||
}
|
||||
|
||||
def save(nbt: NBTTagCompound) {
|
||||
nbt.setNewCompoundTag(Settings.namespace + "buffer", buffer.save)
|
||||
nbt.setNewCompoundTag(Settings.namespace + "keyboard", keyboard.save)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def onScreenColorChange(foreground: Int, background: Int) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenColorChange(buffer, foreground, background)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenCopy(buffer, col, row, w, h, tx, ty)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
def onScreenDepthChange(depth: Depth.Value) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenDepthChange(buffer, depth)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenFill(buffer, col, row, w, h, c)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenResolutionChange(buffer, w, h)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String) {
|
||||
if (isServer) {
|
||||
rack.markAsChanged()
|
||||
ServerPacketSender.sendScreenSet(buffer, col, row, s)
|
||||
}
|
||||
else currentGui.foreach(_.recompileDisplayLists())
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer}
|
||||
|
||||
class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory) extends Player(playerInventory, serverInventory) {
|
||||
for (i <- 0 to 1) {
|
||||
addSlotToContainer(76, 7 + i * slotSize, api.driver.Slot.Card, 1)
|
||||
addSlotToContainer(76, 7 + i * slotSize, api.driver.Slot.Card, 2 - i)
|
||||
}
|
||||
|
||||
for (i <- 0 to 3) {
|
||||
|
@ -18,7 +18,8 @@ trait ServerInventory extends ItemStackInventory {
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
||||
(slot, Registry.itemDriverFor(stack)) match {
|
||||
case (_, None) => false // Invalid item.
|
||||
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= 1
|
||||
case (0, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= 2
|
||||
case (1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= 1
|
||||
case (2 | 3 | 4 | 5, Some(driver)) => driver.slot(stack) == Slot.Processor && driver.tier(stack) <= 2
|
||||
case (6 | 7 | 8 | 9, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= 2
|
||||
case (10 | 11 | 12 | 13, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= 2
|
||||
|
@ -1,5 +1,70 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
import cpw.mods.fml.relauncher.{SideOnly, Side}
|
||||
import java.util
|
||||
import li.cil.oc.common.{GuiType, tileentity}
|
||||
import li.cil.oc.util.Tooltip
|
||||
import li.cil.oc.{OpenComputers, Settings}
|
||||
import net.minecraft.client.renderer.texture.IconRegister
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Terminal(val parent: Delegator) extends Delegate {
|
||||
val unlocalizedName = "Terminal"
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def tooltipLines(stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||
tooltip.addAll(Tooltip.get(unlocalizedName))
|
||||
if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "server")) {
|
||||
val server = stack.getTagCompound.getString(Settings.namespace + "server")
|
||||
tooltip.add("§8" + server.substring(0, 13) + "...§7")
|
||||
}
|
||||
super.tooltipLines(stack, player, tooltip, advanced)
|
||||
}
|
||||
|
||||
override def registerIcons(iconRegister: IconRegister) = {
|
||||
super.registerIcons(iconRegister)
|
||||
|
||||
icon = iconRegister.registerIcon(Settings.resourceDomain + ":terminal")
|
||||
}
|
||||
|
||||
override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
world.getBlockTileEntity(x, y, z) match {
|
||||
case rack: tileentity.Rack if side == rack.facing.ordinal() =>
|
||||
val l = 2 / 16.0
|
||||
val h = 14 / 16.0
|
||||
val s = (((1 - hitY) - l) / (h - l) * 4).toInt
|
||||
if (s >= 0 && s <= 3 && rack.items(s).isDefined) {
|
||||
if (!world.isRemote) {
|
||||
rack.servers(s) match {
|
||||
case Some(server) =>
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound("tag"))
|
||||
}
|
||||
stack.getTagCompound.setString(Settings.namespace + "server", server.machine.address)
|
||||
player.inventory.onInventoryChanged()
|
||||
case _ => // Huh?
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
case _ => super.onItemUseFirst(stack, player, world, x, y, z, side, hitX, hitY, hitZ)
|
||||
}
|
||||
}
|
||||
|
||||
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = {
|
||||
if (!player.isSneaking && stack.hasTagCompound) {
|
||||
val address = stack.getTagCompound.getString(Settings.namespace + "server")
|
||||
if (address != null && !address.isEmpty) {
|
||||
if (world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Terminal.id, world, 0, 0, 0)
|
||||
}
|
||||
player.swingItem()
|
||||
}
|
||||
}
|
||||
super.onItemRightClick(stack, world, player)
|
||||
}
|
||||
}
|
||||
|
@ -2,29 +2,22 @@ package li.cil.oc.common.tileentity
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.client.gui
|
||||
import li.cil.oc.common.component
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.PackedColor
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
trait Buffer extends Environment {
|
||||
trait Buffer extends Environment with component.Buffer.Owner {
|
||||
protected val _buffer = new component.Buffer(this)
|
||||
|
||||
protected var _bufferIsDirty = false
|
||||
|
||||
protected var _currentGui = None: Option[gui.Buffer]
|
||||
|
||||
lazy val buffer = _buffer
|
||||
|
||||
def bufferIsDirty = _bufferIsDirty
|
||||
|
||||
def bufferIsDirty_=(value: Boolean) = _bufferIsDirty = value
|
||||
|
||||
def currentGui = _currentGui
|
||||
|
||||
def currentGui_=(value: Option[gui.Buffer]) = _currentGui = value
|
||||
|
||||
def node: Node = buffer.node
|
||||
|
||||
def tier: Int
|
||||
@ -58,47 +51,47 @@ trait Buffer extends Environment {
|
||||
|
||||
def onScreenColorChange(foreground: Int, background: Int) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenColorChange(this, foreground, background)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenColorChange(buffer, foreground, background)
|
||||
}
|
||||
}
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenCopy(this, col, row, w, h, tx, ty)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenCopy(buffer, col, row, w, h, tx, ty)
|
||||
}
|
||||
else markForRenderUpdate()
|
||||
}
|
||||
|
||||
def onScreenDepthChange(depth: PackedColor.Depth.Value) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenDepthChange(this, depth)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenDepthChange(buffer, depth)
|
||||
}
|
||||
else markForRenderUpdate()
|
||||
}
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenFill(this, col, row, w, h, c)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenFill(buffer, col, row, w, h, c)
|
||||
}
|
||||
else markForRenderUpdate()
|
||||
}
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenResolutionChange(this, w, h)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenResolutionChange(buffer, w, h)
|
||||
}
|
||||
else markForRenderUpdate()
|
||||
}
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String) {
|
||||
if (isServer) {
|
||||
world.markTileEntityChunkModified(x, y, z, this.asInstanceOf[net.minecraft.tileentity.TileEntity])
|
||||
ServerPacketSender.sendScreenSet(this, col, row, s)
|
||||
world.markTileEntityChunkModified(x, y, z, this)
|
||||
ServerPacketSender.sendScreenSet(buffer, col, row, s)
|
||||
}
|
||||
else markForRenderUpdate()
|
||||
}
|
||||
|
@ -12,7 +12,11 @@ import net.minecraftforge.common.ForgeDirection
|
||||
class Keyboard(isRemote: Boolean) extends Environment with SidedEnvironment with Analyzable with Rotatable with PassiveNode {
|
||||
def this() = this(false)
|
||||
|
||||
val keyboard = if (isRemote) null else new component.Keyboard(this)
|
||||
val keyboard = if (isRemote) null else new component.Keyboard {
|
||||
def isUseableByPlayer(p: EntityPlayer) =
|
||||
world.getBlockTileEntity(x, y, z) == Keyboard.this &&
|
||||
p.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||
}
|
||||
|
||||
def node = if (isClient) null else keyboard.node
|
||||
|
||||
|
@ -3,12 +3,13 @@ package li.cil.oc.common.tileentity
|
||||
import cpw.mods.fml.common.Optional
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import li.cil.oc.api.network.{Visibility, Node, Analyzable}
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender, driver, component}
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.{api, Items, Settings}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.nbt.{NBTTagString, NBTTagCompound}
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
import stargatetech2.api.bus.IBusDevice
|
||||
|
||||
@ -19,13 +20,15 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
|
||||
val sides = Array.fill(servers.length)(ForgeDirection.UNKNOWN)
|
||||
|
||||
val terminals = (0 until servers.length).map(new common.component.Terminal(this, _)).toArray
|
||||
|
||||
// For client side, where we don't create the component.
|
||||
private val _isRunning = new Array[Boolean](getSizeInventory)
|
||||
|
||||
private var hasChanged = false
|
||||
|
||||
// For client side rendering.
|
||||
var isPresent = new Array[Boolean](getSizeInventory)
|
||||
var isPresent = Array.fill[Option[String]](getSizeInventory)(None)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@ -147,8 +150,6 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
val sidesNbt = nbt.getByteArray(Settings.namespace + "sides").byteArray.map(ForgeDirection.getOrientation(_))
|
||||
Array.copy(sidesNbt, 0, sides, 0, math.min(sidesNbt.length, sides.length))
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
if (getStackInSlot(slot) != null) {
|
||||
val server = new component.Server(this, slot)
|
||||
@ -161,10 +162,15 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
val sidesNbt = nbt.getByteArray(Settings.namespace + "sides").byteArray.map(ForgeDirection.getOrientation(_))
|
||||
Array.copy(sidesNbt, 0, sides, 0, math.min(sidesNbt.length, sides.length))
|
||||
val terminalsNbt = nbt.getTagList(Settings.namespace + "terminals").iterator[NBTTagCompound].toArray
|
||||
for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) {
|
||||
terminals(i).load(terminalsNbt(i))
|
||||
}
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
nbt.setByteArray(Settings.namespace + "sides", sides.map(_.ordinal.toByte))
|
||||
nbt.setNewTagList(Settings.namespace + "servers", servers map {
|
||||
case Some(server) =>
|
||||
val serverNbt = new NBTTagCompound()
|
||||
@ -173,6 +179,12 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
case _ => new NBTTagCompound()
|
||||
})
|
||||
super.writeToNBT(nbt)
|
||||
nbt.setByteArray(Settings.namespace + "sides", sides.map(_.ordinal.toByte))
|
||||
nbt.setNewTagList(Settings.namespace + "terminals", terminals.map(t => {
|
||||
val terminalNbt = new NBTTagCompound()
|
||||
t.save(terminalNbt)
|
||||
terminalNbt
|
||||
}))
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -180,17 +192,26 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
super.readFromNBTForClient(nbt)
|
||||
val isRunningNbt = nbt.getByteArray("isRunning").byteArray.map(_ == 1)
|
||||
Array.copy(isRunningNbt, 0, _isRunning, 0, math.min(isRunningNbt.length, _isRunning.length))
|
||||
val isPresentNbt = nbt.getByteArray("isPresent").byteArray.map(_ == 1)
|
||||
val isPresentNbt = nbt.getTagList("isPresent").iterator[NBTTagString].map(value => if (value.data == "") None else Some(value.data)).toArray
|
||||
Array.copy(isPresentNbt, 0, isPresent, 0, math.min(isPresentNbt.length, isPresent.length))
|
||||
val sidesNbt = nbt.getByteArray("sides").byteArray.map(ForgeDirection.getOrientation(_))
|
||||
Array.copy(sidesNbt, 0, sides, 0, math.min(sidesNbt.length, sides.length))
|
||||
val terminalsNbt = nbt.getTagList("terminals").iterator[NBTTagCompound].toArray
|
||||
for (i <- 0 until math.min(terminals.length, terminalsNbt.length)) {
|
||||
terminals(i).buffer.buffer.load(terminalsNbt(i))
|
||||
}
|
||||
}
|
||||
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForClient(nbt)
|
||||
nbt.setByteArray("isRunning", _isRunning.map(value => (if (value) 1 else 0).toByte))
|
||||
nbt.setByteArray("isPresent", servers.map(value => (if (value.isDefined) 1 else 0).toByte))
|
||||
nbt.setNewTagList("isPresent", servers.map(value => new NBTTagString(null, value.fold("")(_.machine.address))))
|
||||
nbt.setByteArray("sides", sides.map(_.ordinal.toByte))
|
||||
nbt.setNewTagList("terminals", terminals.map(t => {
|
||||
val terminalNbt = new NBTTagCompound()
|
||||
t.buffer.buffer.save(terminalNbt)
|
||||
terminalNbt
|
||||
}))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -202,6 +223,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
servers(number) match {
|
||||
case Some(server) if toGlobal(serverSide) == plug.side || serverSide == ForgeDirection.UNKNOWN =>
|
||||
plug.node.connect(server.machine.node)
|
||||
terminals(number).connect(server.machine.node)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
@ -218,6 +240,7 @@ class Rack extends Hub with PowerBalancer with Inventory with Rotatable with Bun
|
||||
val server = new component.Server(this, slot)
|
||||
servers(slot) = Some(server)
|
||||
reconnectServer(slot, server)
|
||||
terminals(slot).connect(server.machine.node)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
|
||||
val gpu = new GraphicsCard.Tier1 {
|
||||
override val maxResolution = (48, 14)
|
||||
}
|
||||
val keyboard = new component.Keyboard(this) {
|
||||
val keyboard = new component.Keyboard {
|
||||
override def isUseableByPlayer(p: EntityPlayer) =
|
||||
world.getBlockTileEntity(x, y, z) == proxy &&
|
||||
p.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||
@ -306,11 +306,9 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with ISidedInventory w
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
if (isServer) {
|
||||
buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
|
||||
gpu.load(nbt.getCompoundTag(Settings.namespace + "gpu"))
|
||||
keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
|
||||
}
|
||||
buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
|
||||
gpu.load(nbt.getCompoundTag(Settings.namespace + "gpu"))
|
||||
keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
|
||||
if (nbt.hasKey(Settings.namespace + "owner")) {
|
||||
owner = nbt.getString(Settings.namespace + "owner")
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
|
||||
|
||||
// Convert to absolute coordinates and send the packet to the server.
|
||||
if (world.isRemote) {
|
||||
ClientPacketSender.sendMouseClick(this, (brx * bw).toInt + 1, (bry * bh).toInt + 1, drag = false)
|
||||
ClientPacketSender.sendMouseClick(this.buffer, (brx * bw).toInt + 1, (bry * bh).toInt + 1, drag = false)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -56,59 +56,68 @@ class PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
|
||||
def onKeyDown(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(s: Screen) =>
|
||||
p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Screen) =>
|
||||
val char = Char.box(p.readChar())
|
||||
val code = Int.box(p.readInt())
|
||||
s.screens.foreach(_.node.sendToNeighbors("keyboard.keyDown", p.player, char, code))
|
||||
case Some(e) => e.buffer.node.sendToNeighbors("keyboard.keyDown", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
t.screens.foreach(_.node.sendToNeighbors("keyboard.keyDown", p.player, char, code))
|
||||
case Some(t: Buffer) => t.buffer.node.sendToNeighbors("keyboard.keyDown", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer.node.sendToNeighbors("keyboard.keyDown", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onKeyUp(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(s: Screen) =>
|
||||
p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Screen) =>
|
||||
val char = Char.box(p.readChar())
|
||||
val code = Int.box(p.readInt())
|
||||
s.screens.foreach(_.node.sendToNeighbors("keyboard.keyUp", p.player, char, code))
|
||||
case Some(e) => e.buffer.node.sendToNeighbors("keyboard.keyUp", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
t.screens.foreach(_.node.sendToNeighbors("keyboard.keyUp", p.player, char, code))
|
||||
case Some(t: Buffer) => t.buffer.node.sendToNeighbors("keyboard.keyUp", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer.node.sendToNeighbors("keyboard.keyUp", p.player, Char.box(p.readChar()), Int.box(p.readInt()))
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onClipboard(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(s: Screen) =>
|
||||
p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Screen) =>
|
||||
val value = p.readUTF()
|
||||
s.screens.foreach(_.node.sendToNeighbors("keyboard.clipboard", p.player, value))
|
||||
case Some(e) => e.buffer.node.sendToNeighbors("keyboard.clipboard", p.player, p.readUTF())
|
||||
t.screens.foreach(_.node.sendToNeighbors("keyboard.clipboard", p.player, value))
|
||||
case Some(t: Buffer) => t.buffer.node.sendToNeighbors("keyboard.clipboard", p.player, p.readUTF())
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer.node.sendToNeighbors("keyboard.clipboard", p.player, p.readUTF())
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onMouseClick(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(s: Screen) => p.player match {
|
||||
case player: EntityPlayer =>
|
||||
val x = p.readInt()
|
||||
val y = p.readInt()
|
||||
val what = if (p.readBoolean()) "drag" else "touch"
|
||||
s.origin.node.sendToReachable("computer.checked_signal", player, what, Int.box(x), Int.box(y), player.getCommandSenderName)
|
||||
case _ =>
|
||||
}
|
||||
def onMouseClick(p: PacketParser) {
|
||||
p.player match {
|
||||
case player: EntityPlayer =>
|
||||
val node = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Screen) => t.origin.node
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer.node
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val x = p.readInt()
|
||||
val y = p.readInt()
|
||||
val what = if (p.readBoolean()) "drag" else "touch"
|
||||
node.sendToReachable("computer.checked_signal", player, what, Int.box(x), Int.box(y), player.getCommandSenderName)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
|
||||
def onMouseScroll(p: PacketParser) =
|
||||
p.readTileEntity[Buffer]() match {
|
||||
case Some(s: Screen) => p.player match {
|
||||
case player: EntityPlayer =>
|
||||
val x = p.readInt()
|
||||
val y = p.readInt()
|
||||
val scroll = p.readByte()
|
||||
s.origin.node.sendToReachable("computer.checked_signal", player, "scroll", Int.box(x), Int.box(y), Int.box(scroll), player.getCommandSenderName)
|
||||
case _ =>
|
||||
}
|
||||
def onMouseScroll(p: PacketParser) {
|
||||
p.player match {
|
||||
case player: EntityPlayer =>
|
||||
val node = p.readTileEntity[TileEntity]() match {
|
||||
case Some(t: Screen) => t.origin.node
|
||||
case Some(t: Rack) => t.terminals(p.readInt()).buffer.node
|
||||
case _ => return // Invalid packet.
|
||||
}
|
||||
val x = p.readInt()
|
||||
val y = p.readInt()
|
||||
val scroll = p.readByte()
|
||||
node.sendToReachable("computer.checked_signal", player, "scroll", Int.box(x), Int.box(y), Int.box(scroll), player.getCommandSenderName)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
|
||||
def onServerSide(p: PacketParser) =
|
||||
p.readTileEntity[Rack]() match {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.server
|
||||
|
||||
import cpw.mods.fml.common.network.Player
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.common.PacketBuilder
|
||||
import li.cil.oc.common.PacketType
|
||||
import li.cil.oc.common.tileentity._
|
||||
@ -156,20 +157,38 @@ object PacketSender {
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
||||
def sendScreenColorChange(t: Buffer, foreground: Int, background: Int) {
|
||||
def sendScreenColorChange(b: common.component.Buffer, foreground: Int, background: Int) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenColorChange)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(foreground)
|
||||
pb.writeInt(background)
|
||||
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
||||
def sendScreenCopy(t: Buffer, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
def sendScreenCopy(b: common.component.Buffer, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenCopy)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(col)
|
||||
pb.writeInt(row)
|
||||
pb.writeInt(w)
|
||||
@ -180,19 +199,37 @@ object PacketSender {
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
||||
def sendScreenDepthChange(t: Buffer, value: PackedColor.Depth.Value) {
|
||||
def sendScreenDepthChange(b: common.component.Buffer, value: PackedColor.Depth.Value) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenDepthChange)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(value.id)
|
||||
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
||||
def sendScreenFill(t: Buffer, col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
def sendScreenFill(b: common.component.Buffer, col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenFill)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(col)
|
||||
pb.writeInt(row)
|
||||
pb.writeInt(w)
|
||||
@ -211,20 +248,38 @@ object PacketSender {
|
||||
pb.sendToNearbyPlayers(t, 64)
|
||||
}
|
||||
|
||||
def sendScreenResolutionChange(t: Buffer, w: Int, h: Int) {
|
||||
def sendScreenResolutionChange(b: common.component.Buffer, w: Int, h: Int) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenResolutionChange)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(w)
|
||||
pb.writeInt(h)
|
||||
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
||||
def sendScreenSet(t: Buffer, col: Int, row: Int, s: String) {
|
||||
def sendScreenSet(b: common.component.Buffer, col: Int, row: Int, s: String) {
|
||||
val pb = new PacketBuilder(PacketType.ScreenSet)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
val t = b.owner match {
|
||||
case t: Buffer =>
|
||||
pb.writeTileEntity(t)
|
||||
t
|
||||
case t: common.component.Terminal =>
|
||||
pb.writeTileEntity(t.rack)
|
||||
pb.writeInt(t.number)
|
||||
t.rack
|
||||
case _ => return
|
||||
}
|
||||
pb.writeInt(col)
|
||||
pb.writeInt(row)
|
||||
pb.writeUTF(s)
|
||||
@ -236,7 +291,13 @@ object PacketSender {
|
||||
val pb = new PacketBuilder(PacketType.ServerPresence)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
t.servers.foreach(server => pb.writeBoolean(server.isDefined))
|
||||
t.servers.foreach {
|
||||
case Some(server) =>
|
||||
pb.writeBoolean(true)
|
||||
pb.writeUTF(server.machine.address)
|
||||
case _ =>
|
||||
pb.writeBoolean(false)
|
||||
}
|
||||
|
||||
pb.sendToNearbyPlayers(t)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package li.cil.oc.server.component
|
||||
import cpw.mods.fml.common.IPlayerTracker
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.network.{Node, Visibility, Message}
|
||||
import li.cil.oc.common.tileentity.Environment
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.event.{Event, ForgeSubscribe}
|
||||
@ -12,7 +11,7 @@ import scala.collection.mutable
|
||||
// TODO key up when screen is disconnected from which the key down came
|
||||
// TODO key up after load for anything that was pressed
|
||||
|
||||
class Keyboard(owner: Environment) extends ManagedComponent {
|
||||
abstract class Keyboard extends ManagedComponent {
|
||||
val node = Network.newNode(this, Visibility.Network).
|
||||
withComponent("keyboard").
|
||||
create()
|
||||
@ -71,9 +70,7 @@ class Keyboard(owner: Environment) extends ManagedComponent {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def isUseableByPlayer(p: EntityPlayer) =
|
||||
owner.world.getBlockTileEntity(owner.x, owner.y, owner.z) == owner &&
|
||||
p.getDistanceSq(owner.x + 0.5, owner.y + 0.5, owner.z + 0.5) <= 64
|
||||
def isUseableByPlayer(p: EntityPlayer): Boolean
|
||||
|
||||
protected def signal(args: AnyRef*) =
|
||||
node.sendToReachable("computer.checked_signal", args: _*)
|
||||
|
@ -711,6 +711,7 @@ class Machine(val owner: Machine.Owner) extends ManagedComponent with Context wi
|
||||
switchTo(Machine.State.Stopping)
|
||||
}
|
||||
case result: ExecutionResult.Error =>
|
||||
crash(result.message)
|
||||
}
|
||||
case Machine.State.Paused =>
|
||||
state.pop() // Paused
|
||||
|
@ -29,6 +29,8 @@ class Server(val rack: tileentity.Rack, val number: Int) extends Machine.Owner {
|
||||
override def getInventoryStackLimit = 1
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def installedMemory = inventory.items.foldLeft(0)((sum, stack) => sum + (stack match {
|
||||
case Some(item) => Registry.itemDriverFor(item) match {
|
||||
case Some(driver: driver.Memory) => driver.amount(item)
|
||||
@ -49,6 +51,8 @@ class Server(val rack: tileentity.Rack, val number: Int) extends Machine.Owner {
|
||||
|
||||
def markAsChanged() = rack.markAsChanged()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onConnect(node: Node) = inventory.onConnect(node)
|
||||
|
||||
override def onDisconnect(node: Node) = inventory.onDisconnect(node)
|
||||
|
Loading…
x
Reference in New Issue
Block a user