added a new interface to the api that allows tile entity environments to add more information when the analyzer tool is used on them; removed check for analyzer in delegator block, must be sneaking for some blocks to use it now (screen, computer, disk drive) and keep control pressed in addition to sneaking to copy the address to the clipboard (hardcoded keys, yay... may make it configurable some day... or not); rotation was kinda working but not fully (could not change yaw for blocks that faced up or down), now it works for all cases (probably); forcing render update when rotating blocks (computer block didn't re-render, for example)

This commit is contained in:
Florian Nücke 2013-11-12 02:00:44 +01:00
parent b4668873c2
commit f1ed542441
8 changed files with 90 additions and 34 deletions

View File

@ -0,0 +1,34 @@
package li.cil.oc.api.network;
import net.minecraft.entity.player.EntityPlayer;
/**
* Allows defining a callback for when a block is right-clicked with an
* analyzer.
* <p/>
* This has to be implemented by a {@link net.minecraft.tileentity.TileEntity},
* else it will have no effect.
*/
public interface Analyzable extends Environment {
/**
* Called when a player uses the analyzer tool on the tile entity's block.
* <p/>
* This can be used to display additional block specific information in the
* player's chat when the analyzer is used (or do whatever) and may also be
* used to redirect the query to some other environment by returning some
* other environment than <tt>this</tt>. The latter is used by multi-block
* screens, for example, to always show information of the primary screen.
* <p/>
* Return <tt>null</tt> to suppress any further node information being
* displayed.
*
* @param player the player that used the analyzer.
* @param side the side of the block the player clicked.
* @param hitX the relative X coordinate the player clicked.
* @param hitY the relative Y coordinate the player clicked.
* @param hitZ the relative Z coordinate the player clicked.
* @return the environment to display node information for, usually the
* environment itself (i.e. just return <tt>this</tt>).
*/
Environment onAnalyze(EntityPlayer player, int side, float hitX, float hitY, float hitZ);
}

View File

@ -10,6 +10,7 @@ import net.minecraft.client.gui.GuiScreen
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.ForgeDirection
import org.lwjgl.input.Keyboard
class PacketHandler extends CommonPacketHandler {
protected override def world(player: Player, dimension: Int) = {
@ -36,8 +37,10 @@ class PacketHandler extends CommonPacketHandler {
}
def onClipboard(p: PacketParser) = {
GuiScreen.setClipboardString(p.readUTF())
p.player.asInstanceOf[EntityPlayer].addChatMessage("Copied to clipboard.")
if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) {
GuiScreen.setClipboardString(p.readUTF())
p.player.asInstanceOf[EntityPlayer].addChatMessage("Copied to clipboard.")
}
}
def onComputerStateResponse(p: PacketParser) =

View File

@ -4,7 +4,7 @@ import cpw.mods.fml.common.registry.GameRegistry
import java.util
import li.cil.oc.api.network.Environment
import li.cil.oc.common.tileentity.Rotatable
import li.cil.oc.{Items, Config, CreativeTab}
import li.cil.oc.{Config, CreativeTab}
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IconRegister
@ -233,10 +233,6 @@ 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 = {
// 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
// wrenches. This structural type is compatible with the BuildCraft wrench
// interface.
@ -331,12 +327,13 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) {
case _ => true
}) && super.removeBlockByPlayer(world, player, x, y, z)
override def rotateBlock(world: World, x: Int, y: Int, z: Int, axis: ForgeDirection) = {
val newFacing = getFacing(world, x, y, z).getRotation(axis)
if (getValidRotations(world, x, y, z).contains(newFacing))
setFacing(world, x, y, z, newFacing)
else false
}
override def rotateBlock(world: World, x: Int, y: Int, z: Int, axis: ForgeDirection) =
world.getBlockTileEntity(x, y, z) match {
case rotatable: Rotatable if rotatable.rotate(axis) =>
world.markBlockForRenderUpdate(x, y, z)
true
case _ => false
}
}
class SimpleDelegator(id: Int) extends Delegator[SimpleDelegate](id)

View File

@ -28,7 +28,8 @@ class Item(id: Int) extends ItemBlock(id) {
// If it's a rotatable block try to make it face the player.
world.getBlockTileEntity(x, y, z) match {
case rotatable: Rotatable =>
rotatable.setFromEntityPitchAndYaw(player).invertRotation()
rotatable.setFromEntityPitchAndYaw(player)
rotatable.invertRotation()
case _ => // Ignore.
}
true

View File

@ -2,8 +2,7 @@ package li.cil.oc.common.item
import cpw.mods.fml.common.network.Player
import li.cil.oc.Config
import li.cil.oc.api.network.{Connector, Environment}
import li.cil.oc.common.tileentity
import li.cil.oc.api.network.{Analyzable, Connector, Environment}
import li.cil.oc.server.PacketSender
import net.minecraft.client.renderer.texture.IconRegister
import net.minecraft.entity.player.EntityPlayer
@ -15,18 +14,9 @@ class Analyzer(val parent: Delegator) extends Delegate {
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 =>
case analyzable: Analyzable =>
if (!world.isRemote) {
computer.instance.lastError match {
case Some(value) => player.addChatMessage("Last error: " + value)
case _ =>
}
analyzeNode(computer, player)
}
true
case screen: tileentity.Screen =>
if (!world.isRemote) {
analyzeNode(screen.origin, player)
analyzeNode(analyzable.onAnalyze(player, side, hitX, hitY, hitZ), player)
}
true
case environment: Environment =>
@ -38,7 +28,7 @@ class Analyzer(val parent: Delegator) extends Delegate {
}
}
private def analyzeNode(environment: Environment, player: EntityPlayer) {
private def analyzeNode(environment: Environment, player: EntityPlayer) = if (environment != null) {
environment.node match {
case connector: Connector =>
player.addChatMessage("Power: %.2f/%.2f".format(connector.buffer, connector.bufferSize))

View File

@ -4,6 +4,7 @@ import cpw.mods.fml.common.Loader
import li.cil.oc.Config
import li.cil.oc.api.Network
import li.cil.oc.api.driver.Slot
import li.cil.oc.api.network.Analyzable
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.server.component
import li.cil.oc.server.component.Computer.{Environment => ComputerEnvironment}
@ -17,7 +18,7 @@ import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.ForgeDirection
class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment with ComponentInventory with Redstone {
class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment with ComponentInventory with Redstone with Analyzable {
def this() = this(false)
// ----------------------------------------------------------------------- //
@ -50,6 +51,16 @@ class Computer(isClient: Boolean) extends Rotatable with ComputerEnvironment wit
// ----------------------------------------------------------------------- //
def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = {
instance.lastError match {
case Some(value) => player.addChatMessage("Last error: " + value)
case _ =>
}
this
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
super.load(nbt)

View File

@ -127,6 +127,16 @@ abstract class Rotatable extends TileEntity {
case _ => _yaw
}
def rotate(axis: ForgeDirection) = {
val (newPitch, newYaw) = facing.getRotation(axis) match {
case value@(ForgeDirection.UP | ForgeDirection.DOWN) =>
if (value == pitch) (value, yaw.getRotation(axis))
else (value, yaw)
case value => (ForgeDirection.NORTH, value)
}
trySetPitchYaw(newPitch, newYaw)
}
def toLocal(value: ForgeDirection) = cachedTranslation(value.ordinal)
def toGlobal(value: ForgeDirection) = cachedInverseTranslation(value.ordinal)
@ -173,16 +183,21 @@ abstract class Rotatable extends TileEntity {
/** Validates new values against the allowed rotations as set in our block. */
private def trySetPitchYaw(pitch: ForgeDirection, yaw: ForgeDirection) = {
var changed = false
val block = Block.blocksList(worldObj.getBlockId(xCoord, yCoord, zCoord))
if (block != null) {
val valid = block.getValidRotations(worldObj, xCoord, yCoord, zCoord)
if (valid.contains(pitch))
if (valid.contains(pitch)) {
changed = true
_pitch = pitch
if (valid.contains(yaw))
}
if (valid.contains(yaw)) {
changed = true
_yaw = yaw
}
updateTranslation()
}
this
changed
}
private def invert(t: Array[ForgeDirection]) =

View File

@ -2,13 +2,14 @@ package li.cil.oc.common.tileentity
import li.cil.oc.Config
import li.cil.oc.api.Network
import li.cil.oc.api.network.Visibility
import li.cil.oc.api.network.{Analyzable, Visibility}
import li.cil.oc.client.gui
import li.cil.oc.client.{PacketSender => ClientPacketSender}
import li.cil.oc.common.component.Screen.{Environment => ScreenEnvironment}
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.PackedColor
import net.minecraft.client.Minecraft
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.AxisAlignedBB
import net.minecraftforge.common.ForgeDirection
@ -26,7 +27,7 @@ class ScreenTier3 extends Screen {
protected def tier = 2
}
abstract class Screen extends Rotatable with ScreenEnvironment {
abstract class Screen extends Rotatable with ScreenEnvironment with Analyzable {
var currentGui: Option[gui.Screen] = None
/**
@ -68,6 +69,10 @@ abstract class Screen extends Rotatable with ScreenEnvironment {
// ----------------------------------------------------------------------- //
def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = origin
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
super.load(nbt)