added analyzer tool: right click on a block show its address. for computers it also shows the last error message, if any (if the computer crashed). for multi screens it always shows the address of the origin. shift-rightclick copies the address to the clipboard.

This commit is contained in:
Florian Nücke 2013-11-09 23:38:17 +01:00
parent a7d21190be
commit 39b2c97010
11 changed files with 97 additions and 14 deletions

View File

@ -9,8 +9,8 @@ oc.block.ScreenBasic.name=Einfacher Bildschirm
oc.block.ScreenProfessional.name=Professioneller Bildschirm oc.block.ScreenProfessional.name=Professioneller Bildschirm
oc.container.Computer=Computer oc.container.Computer=Computer
oc.container.DiskDrive=Diskettenlaufwerk oc.container.DiskDrive=Diskettenlaufwerk
oc.item.Analyzer.name=Messgerät
oc.item.Disk.name=Diskette oc.item.Disk.name=Diskette
oc.item.GraphicsCard.name=
oc.item.GraphicsCardAdvanced.name=Hochwertige Grafikkarte oc.item.GraphicsCardAdvanced.name=Hochwertige Grafikkarte
oc.item.GraphicsCardBasic.name=Einfache Grafikkarte oc.item.GraphicsCardBasic.name=Einfache Grafikkarte
oc.item.GraphicsCardProfessional.name=Professionelle Grafikkarte oc.item.GraphicsCardProfessional.name=Professionelle Grafikkarte

View File

@ -9,6 +9,7 @@ oc.block.ScreenBasic.name=Basic Screen
oc.block.ScreenProfessional.name=Professional Screen oc.block.ScreenProfessional.name=Professional Screen
oc.container.Computer=Computer oc.container.Computer=Computer
oc.container.DiskDrive=Disk Drive oc.container.DiskDrive=Disk Drive
oc.item.Analyzer.name=Analyzer
oc.item.Disk.name=Floppy Disk oc.item.Disk.name=Floppy Disk
oc.item.GraphicsCardAdvanced.name=Advanced Graphics Card oc.item.GraphicsCardAdvanced.name=Advanced Graphics Card
oc.item.GraphicsCardBasic.name=Basic Graphics Card oc.item.GraphicsCardBasic.name=Basic Graphics Card

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

View File

@ -23,6 +23,8 @@ object Items {
var hdd3: item.HardDiskDrive = null var hdd3: item.HardDiskDrive = null
var disk: item.Disk = null var disk: item.Disk = null
var analyzer: item.Analyzer = null
def init() { def init() {
multi = new item.Delegator(Config.itemId) multi = new item.Delegator(Config.itemId)
@ -44,5 +46,7 @@ object Items {
psu = new item.PowerSupply(multi) psu = new item.PowerSupply(multi)
wlan = new item.WirelessNetworkCard(multi) wlan = new item.WirelessNetworkCard(multi)
analyzer = new item.Analyzer(multi)
} }
} }

View File

@ -5,6 +5,7 @@ import li.cil.oc.common.PacketType
import li.cil.oc.common.tileentity.{PowerDistributor, Computer, Rotatable, Screen} import li.cil.oc.common.tileentity.{PowerDistributor, Computer, Rotatable, Screen}
import li.cil.oc.common.{PacketHandler => CommonPacketHandler} import li.cil.oc.common.{PacketHandler => CommonPacketHandler}
import li.cil.oc.server.component.Redstone import li.cil.oc.server.component.Redstone
import net.minecraft.client.gui.GuiScreen
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
import net.minecraft.tileentity.TileEntity import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.ForgeDirection import net.minecraftforge.common.ForgeDirection
@ -18,6 +19,7 @@ class PacketHandler extends CommonPacketHandler {
override def dispatch(p: PacketParser) = override def dispatch(p: PacketParser) =
p.packetType match { p.packetType match {
case PacketType.Clipboard => onClipboard(p)
case PacketType.ComputerStateResponse => onComputerStateResponse(p) case PacketType.ComputerStateResponse => onComputerStateResponse(p)
case PacketType.PowerStateResponse => onPowerStateResponse(p) case PacketType.PowerStateResponse => onPowerStateResponse(p)
case PacketType.RedstoneStateResponse => onRedstoneStateResponse(p) case PacketType.RedstoneStateResponse => onRedstoneStateResponse(p)
@ -30,6 +32,11 @@ class PacketHandler extends CommonPacketHandler {
case _ => // Invalid packet. case _ => // Invalid packet.
} }
def onClipboard(p: PacketParser) = {
GuiScreen.setClipboardString(p.readUTF())
p.player.asInstanceOf[EntityPlayer].addChatMessage("Copied to clipboard.")
}
def onComputerStateResponse(p: PacketParser) = def onComputerStateResponse(p: PacketParser) =
p.readTileEntity[Computer]() match { p.readTileEntity[Computer]() match {
case Some(t) => { case Some(t) => {

View File

@ -2,10 +2,9 @@ package li.cil.oc.common.block
import cpw.mods.fml.common.registry.GameRegistry import cpw.mods.fml.common.registry.GameRegistry
import java.util import java.util
import li.cil.oc.Config
import li.cil.oc.CreativeTab
import li.cil.oc.api.network.Environment import li.cil.oc.api.network.Environment
import li.cil.oc.common.tileentity.Rotatable import li.cil.oc.common.tileentity.Rotatable
import li.cil.oc.{Items, Config, CreativeTab}
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.block.material.Material import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IconRegister import net.minecraft.client.renderer.texture.IconRegister
@ -234,6 +233,10 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) {
} }
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
// Do nothing if we have an analyzer in hand.
if (Items.analyzer.equals(player.getCurrentEquippedItem))
return false
// Helper method to detect items that can be used to rotate blocks, such as // Helper method to detect items that can be used to rotate blocks, such as
// wrenches. This structural type is compatible with the BuildCraft wrench // wrenches. This structural type is compatible with the BuildCraft wrench
// interface. // interface.

View File

@ -0,0 +1,54 @@
package li.cil.oc.common.item
import cpw.mods.fml.common.network.Player
import li.cil.oc.Config
import li.cil.oc.api.network.Environment
import li.cil.oc.common.tileentity
import li.cil.oc.server.PacketSender
import net.minecraft.client.renderer.texture.IconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.world.World
class Analyzer(val parent: Delegator) extends Delegate {
val unlocalizedName = "Analyzer"
override def onItemUse(item: 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 computer: tileentity.Computer =>
if (!world.isRemote) {
computer.instance.lastError match {
case Some(value) => player.addChatMessage("Last error: " + value)
case _ =>
}
processAddress(computer, player)
}
true
case screen: tileentity.Screen =>
if (!world.isRemote) {
processAddress(screen.origin, player)
}
true
case environment: Environment =>
if (!world.isRemote) {
processAddress(environment, player)
}
true
case _ => super.onItemUse(item, player, world, x, y, z, side, hitX, hitY, hitZ)
}
}
private def processAddress(environment: Environment, player: EntityPlayer) {
val address = environment.node.address()
player.addChatMessage("Address: " + address)
if (player.isSneaking) {
PacketSender.sendClipboard(address, player.asInstanceOf[Player])
}
}
override def registerIcons(iconRegister: IconRegister) {
super.registerIcons(iconRegister)
icon = iconRegister.registerIcon(Config.resourceDomain + ":analyzer")
}
}

View File

@ -30,4 +30,7 @@ trait Delegate {
def onItemUse(item: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = false def onItemUse(item: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = false
def registerIcons(iconRegister: IconRegister) {} def registerIcons(iconRegister: IconRegister) {}
def equals(item: ItemStack) =
item != null && item.itemID == parent.itemID && parent.subItem(item).exists(_.itemId == itemId)
} }

View File

@ -75,8 +75,7 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit
// otherwise loose track of its screen). // otherwise loose track of its screen).
instance.update() instance.update()
if (isRunning && !node.changeBuffer(-Config.computerBaseCost)) { if (isRunning && !node.changeBuffer(-Config.computerBaseCost)) {
// TODO try to print to screen? sound effect? particle effect? instance.lastError = "not enough power"
println("not enough power, shutting down... ")
turnOff() turnOff()
} }
if (hasChanged) { if (hasChanged) {

View File

@ -10,7 +10,15 @@ import net.minecraftforge.common.ForgeDirection
/** Centralized packet dispatcher for sending updates to the client. */ /** Centralized packet dispatcher for sending updates to the client. */
object PacketSender { object PacketSender {
def sendComputerState(t: TileEntity, value: Boolean, player: Option[Player] = None) = { def sendClipboard(value: String, player: Player) {
val pb = new PacketBuilder(PacketType.Clipboard)
pb.writeUTF(value)
pb.sendToPlayer(player)
}
def sendComputerState(t: TileEntity, value: Boolean, player: Option[Player] = None) {
val pb = new PacketBuilder(PacketType.ComputerStateResponse) val pb = new PacketBuilder(PacketType.ComputerStateResponse)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -22,7 +30,7 @@ object PacketSender {
} }
} }
def sendPowerState(t: PowerDistributor, player: Option[Player] = None) = { def sendPowerState(t: PowerDistributor, player: Option[Player] = None) {
val pb = new PacketBuilder(PacketType.PowerStateResponse) val pb = new PacketBuilder(PacketType.PowerStateResponse)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -34,7 +42,7 @@ object PacketSender {
} }
} }
def sendRedstoneState(t: TileEntity with Redstone, player: Option[Player] = None) = { def sendRedstoneState(t: TileEntity with Redstone, player: Option[Player] = None) {
val pb = new PacketBuilder(PacketType.RedstoneStateResponse) val pb = new PacketBuilder(PacketType.RedstoneStateResponse)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -49,7 +57,7 @@ object PacketSender {
} }
} }
def sendRotatableState(t: Rotatable, player: Option[Player] = None) = { def sendRotatableState(t: Rotatable, player: Option[Player] = None) {
val pb = new PacketBuilder(PacketType.RotatableStateResponse) val pb = new PacketBuilder(PacketType.RotatableStateResponse)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -62,7 +70,7 @@ object PacketSender {
} }
} }
def sendScreenBufferState(t: TileEntity, w: Int, h: Int, text: String, player: Option[Player] = None) = { def sendScreenBufferState(t: TileEntity, w: Int, h: Int, text: String, player: Option[Player] = None) {
val pb = new PacketBuilder(PacketType.ScreenBufferResponse) val pb = new PacketBuilder(PacketType.ScreenBufferResponse)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -76,7 +84,7 @@ object PacketSender {
} }
} }
def sendScreenCopy(t: TileEntity, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) = { def sendScreenCopy(t: TileEntity, col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
val pb = new PacketBuilder(PacketType.ScreenCopy) val pb = new PacketBuilder(PacketType.ScreenCopy)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -90,7 +98,7 @@ object PacketSender {
pb.sendToAllPlayers() pb.sendToAllPlayers()
} }
def sendScreenFill(t: TileEntity, col: Int, row: Int, w: Int, h: Int, c: Char) = { def sendScreenFill(t: TileEntity, col: Int, row: Int, w: Int, h: Int, c: Char) {
val pb = new PacketBuilder(PacketType.ScreenFill) val pb = new PacketBuilder(PacketType.ScreenFill)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -103,7 +111,7 @@ object PacketSender {
pb.sendToAllPlayers() pb.sendToAllPlayers()
} }
def sendScreenResolutionChange(t: TileEntity, w: Int, h: Int) = { def sendScreenResolutionChange(t: TileEntity, w: Int, h: Int) {
val pb = new PacketBuilder(PacketType.ScreenResolutionChange) val pb = new PacketBuilder(PacketType.ScreenResolutionChange)
pb.writeTileEntity(t) pb.writeTileEntity(t)
@ -113,7 +121,7 @@ object PacketSender {
pb.sendToAllPlayers() pb.sendToAllPlayers()
} }
def sendScreenSet(t: TileEntity, col: Int, row: Int, s: String) = { def sendScreenSet(t: TileEntity, col: Int, row: Int, s: String) {
val pb = new PacketBuilder(PacketType.ScreenSet) val pb = new PacketBuilder(PacketType.ScreenSet)
pb.writeTileEntity(t) pb.writeTileEntity(t)

View File

@ -77,6 +77,10 @@ class Computer(val owner: Computer.Environment) extends Persistable with Runnabl
lua.setTotalMemory(kernelMemory + owner.installedMemory) lua.setTotalMemory(kernelMemory + owner.installedMemory)
}) })
def lastError = message
def lastError_=(value: String) = message = Option(value)
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
def start() = state.synchronized(owner.node.network != null && def start() = state.synchronized(owner.node.network != null &&