mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
wrapped robot tile entity in a proxy that gets placed into the world instead, which allows more natural cleanup in minecraft (meaning we don't have to use cheap tricks like manipulating the tile entity list directly); robot rendering and animations
This commit is contained in:
parent
920d485f18
commit
ca606686d3
BIN
assets/opencomputers/textures/blocks/robot.png
Normal file
BIN
assets/opencomputers/textures/blocks/robot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 648 B |
@ -16,7 +16,7 @@ object Blocks {
|
|||||||
var keyboard: Keyboard = null
|
var keyboard: Keyboard = null
|
||||||
var powerDistributor: PowerDistributor = null
|
var powerDistributor: PowerDistributor = null
|
||||||
var powerSupply: PowerConverter = null
|
var powerSupply: PowerConverter = null
|
||||||
var robot: Robot = null
|
var robotProxy: RobotProxy = null
|
||||||
var robotAfterimage: RobotAfterimage = null
|
var robotAfterimage: RobotAfterimage = null
|
||||||
var screen1, screen2, screen3: Screen = null
|
var screen1, screen2, screen3: Screen = null
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ object Blocks {
|
|||||||
GameRegistry.registerTileEntity(classOf[tileentity.Keyboard], Config.namespace + "keyboard")
|
GameRegistry.registerTileEntity(classOf[tileentity.Keyboard], Config.namespace + "keyboard")
|
||||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerConverter], Config.namespace + "power_converter")
|
GameRegistry.registerTileEntity(classOf[tileentity.PowerConverter], Config.namespace + "power_converter")
|
||||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerDistributor], Config.namespace + "power_distributor")
|
GameRegistry.registerTileEntity(classOf[tileentity.PowerDistributor], Config.namespace + "power_distributor")
|
||||||
GameRegistry.registerTileEntity(classOf[tileentity.Robot], Config.namespace + "robot")
|
GameRegistry.registerTileEntity(classOf[tileentity.RobotProxy], Config.namespace + "robot")
|
||||||
GameRegistry.registerTileEntity(classOf[tileentity.Screen], Config.namespace + "screen")
|
GameRegistry.registerTileEntity(classOf[tileentity.Screen], Config.namespace + "screen")
|
||||||
|
|
||||||
// IMPORTANT: the multi block must come first, since the sub blocks will
|
// IMPORTANT: the multi block must come first, since the sub blocks will
|
||||||
@ -53,7 +53,7 @@ object Blocks {
|
|||||||
screen3 = new Screen.Tier3(blockSimple)
|
screen3 = new Screen.Tier3(blockSimple)
|
||||||
|
|
||||||
capacitor = new Capacitor(blockSimple)
|
capacitor = new Capacitor(blockSimple)
|
||||||
robot = new Robot(blockSpecial)
|
robotProxy = new RobotProxy(blockSpecial)
|
||||||
robotAfterimage = new RobotAfterimage(blockSpecial)
|
robotAfterimage = new RobotAfterimage(blockSpecial)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,8 +12,8 @@ object GuiHandler extends CommonGuiHandler {
|
|||||||
new gui.Case(player.inventory, computer)
|
new gui.Case(player.inventory, computer)
|
||||||
case drive: tileentity.DiskDrive if id == GuiType.DiskDrive.id =>
|
case drive: tileentity.DiskDrive if id == GuiType.DiskDrive.id =>
|
||||||
new gui.DiskDrive(player.inventory, drive)
|
new gui.DiskDrive(player.inventory, drive)
|
||||||
case robot: tileentity.Robot if id == GuiType.Robot.id =>
|
case proxy: tileentity.RobotProxy if id == GuiType.Robot.id =>
|
||||||
new gui.Robot(player.inventory, robot)
|
new gui.Robot(player.inventory, proxy.robot)
|
||||||
case screen: tileentity.Screen if id == GuiType.Screen.id =>
|
case screen: tileentity.Screen if id == GuiType.Screen.id =>
|
||||||
new gui.Screen(screen)
|
new gui.Screen(screen)
|
||||||
case _ => null
|
case _ => null
|
||||||
|
@ -27,6 +27,9 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
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)
|
||||||
|
case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p)
|
||||||
|
case PacketType.RobotAnimateTurn => onRobotAnimateTurn(p)
|
||||||
|
case PacketType.RobotEquippedItemChange => onRobotEquippedItemChange(p)
|
||||||
case PacketType.RobotMove => onRobotMove(p)
|
case PacketType.RobotMove => onRobotMove(p)
|
||||||
case PacketType.RobotSelectedSlotChange => onRobotSelectedSlotChange(p)
|
case PacketType.RobotSelectedSlotChange => onRobotSelectedSlotChange(p)
|
||||||
case PacketType.RobotStateResponse => onRobotStateResponse(p)
|
case PacketType.RobotStateResponse => onRobotStateResponse(p)
|
||||||
@ -80,26 +83,46 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def onRobotAnimateSwing(p: PacketParser) =
|
||||||
|
p.readTileEntity[RobotProxy]() match {
|
||||||
|
case Some(t) => t.robot.setAnimateSwing(p.readInt())
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
|
def onRobotAnimateTurn(p: PacketParser) =
|
||||||
|
p.readTileEntity[RobotProxy]() match {
|
||||||
|
case Some(t) => t.robot.setAnimateTurn(p.readByte(), p.readInt())
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
|
def onRobotEquippedItemChange(p: PacketParser) =
|
||||||
|
p.readTileEntity[RobotProxy]() match {
|
||||||
|
case Some(t) => t.robot.equippedItem = Option(p.readItemStack())
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
def onRobotMove(p: PacketParser) =
|
def onRobotMove(p: PacketParser) =
|
||||||
p.readTileEntity[Robot]() match {
|
p.readTileEntity[RobotProxy]() match {
|
||||||
case Some(t) => t.move(p.readDirection())
|
case Some(t) => t.robot.move(p.readDirection())
|
||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
def onRobotSelectedSlotChange(p: PacketParser) =
|
def onRobotSelectedSlotChange(p: PacketParser) =
|
||||||
p.readTileEntity[Robot]() match {
|
p.readTileEntity[RobotProxy]() match {
|
||||||
case Some(t) => t.selectedSlot = p.readInt()
|
case Some(t) => t.robot.selectedSlot = p.readInt()
|
||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
def onRobotStateResponse(p: PacketParser) =
|
def onRobotStateResponse(p: PacketParser) =
|
||||||
p.readTileEntity[Robot]() match {
|
p.readTileEntity[RobotProxy]() match {
|
||||||
case Some(t) =>
|
case Some(t) =>
|
||||||
t.selectedSlot = p.readInt()
|
t.robot.selectedSlot = p.readInt()
|
||||||
t.animationTicksTotal = p.readInt()
|
t.robot.equippedItem = Option(p.readItemStack())
|
||||||
t.animationTicksLeft = p.readInt()
|
t.robot.animationTicksTotal = p.readInt()
|
||||||
t.moveDirection = p.readDirection()
|
t.robot.animationTicksLeft = p.readInt()
|
||||||
t.turnOldFacing = p.readDirection()
|
t.robot.moveDirection = p.readDirection()
|
||||||
|
t.robot.swingingTool = p.readBoolean()
|
||||||
|
t.robot.turnAxis = p.readByte()
|
||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import cpw.mods.fml.common.network.NetworkRegistry
|
|||||||
import cpw.mods.fml.common.registry.TickRegistry
|
import cpw.mods.fml.common.registry.TickRegistry
|
||||||
import cpw.mods.fml.relauncher.Side
|
import cpw.mods.fml.relauncher.Side
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import li.cil.oc.client.renderer.tileentity.{CableRenderer, PowerDistributorRenderer, ScreenRenderer, CaseRenderer}
|
import li.cil.oc.client.renderer.tileentity._
|
||||||
import li.cil.oc.common.tileentity
|
import li.cil.oc.common.tileentity
|
||||||
import li.cil.oc.common.{Proxy => CommonProxy}
|
import li.cil.oc.common.{Proxy => CommonProxy}
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
@ -20,6 +20,7 @@ private[oc] class Proxy extends CommonProxy {
|
|||||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Cable], CableRenderer)
|
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Cable], CableRenderer)
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Case], CaseRenderer)
|
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Case], CaseRenderer)
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.PowerDistributor], PowerDistributorRenderer)
|
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.PowerDistributor], PowerDistributorRenderer)
|
||||||
|
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.RobotProxy], RobotRenderer)
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer)
|
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer)
|
||||||
|
|
||||||
TickRegistry.registerTickHandler(ScreenRenderer, Side.CLIENT)
|
TickRegistry.registerTickHandler(ScreenRenderer, Side.CLIENT)
|
||||||
|
@ -125,7 +125,7 @@ object CableRenderer extends TileEntitySpecialRenderer {
|
|||||||
def renderTileEntityAt(t: TileEntity, x: Double, y: Double, z: Double, f: Float) {
|
def renderTileEntityAt(t: TileEntity, x: Double, y: Double, z: Double, f: Float) {
|
||||||
val cable = t.asInstanceOf[Cable]
|
val cable = t.asInstanceOf[Cable]
|
||||||
|
|
||||||
val l = t.getWorldObj.getLightBrightnessForSkyBlocks(t.xCoord, t.yCoord, t.zCoord, 0)
|
val l = t.getWorldObj.getLightBrightnessForSkyBlocks(cable.x, cable.y, cable.z, 0)
|
||||||
val l1 = l % 65536
|
val l1 = l % 65536
|
||||||
val l2 = l / 65536
|
val l2 = l / 65536
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, l1, l2)
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, l1, l2)
|
||||||
|
180
li/cil/oc/client/renderer/tileentity/RobotRenderer.scala
Normal file
180
li/cil/oc/client/renderer/tileentity/RobotRenderer.scala
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package li.cil.oc.client.renderer.tileentity
|
||||||
|
|
||||||
|
import java.util.logging.Level
|
||||||
|
import li.cil.oc.common.tileentity
|
||||||
|
import li.cil.oc.{OpenComputers, Config}
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||||
|
import net.minecraft.client.renderer.{OpenGlHelper, Tessellator, GLAllocation}
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
import org.lwjgl.opengl.GL11
|
||||||
|
import li.cil.oc.util.RenderState
|
||||||
|
|
||||||
|
object RobotRenderer extends TileEntitySpecialRenderer {
|
||||||
|
private val texture = new ResourceLocation(Config.resourceDomain, "textures/blocks/robot.png")
|
||||||
|
|
||||||
|
private val displayList = GLAllocation.generateDisplayLists(1)
|
||||||
|
|
||||||
|
private val gap = 1.0 / 28.0
|
||||||
|
private val gt = 0.5 + gap
|
||||||
|
private val gb = 0.5 - gap
|
||||||
|
|
||||||
|
def compileList() {
|
||||||
|
val t = Tessellator.instance
|
||||||
|
|
||||||
|
val size = 0.4
|
||||||
|
val l = 0.5 - size
|
||||||
|
val h = 0.5 + size
|
||||||
|
|
||||||
|
GL11.glNewList(displayList, GL11.GL_COMPILE)
|
||||||
|
|
||||||
|
t.startDrawing(GL11.GL_TRIANGLE_FAN)
|
||||||
|
t.addVertexWithUV(0.5, 1, 0.5, 0.25, 0.25)
|
||||||
|
t.addVertexWithUV(l, gt, h, 0, 0.5)
|
||||||
|
t.addVertexWithUV(h, gt, h, 0.5, 0.5)
|
||||||
|
t.addVertexWithUV(h, gt, l, 0.5, 0)
|
||||||
|
t.addVertexWithUV(l, gt, l, 0, 0)
|
||||||
|
t.addVertexWithUV(l, gt, h, 0, 0.5)
|
||||||
|
t.draw()
|
||||||
|
|
||||||
|
t.startDrawingQuads()
|
||||||
|
t.addVertexWithUV(l, gt, h, 0, 1)
|
||||||
|
t.addVertexWithUV(l, gt, l, 0, 0.5)
|
||||||
|
t.addVertexWithUV(h, gt, l, 0.5, 0.5)
|
||||||
|
t.addVertexWithUV(h, gt, h, 0.5, 1)
|
||||||
|
t.draw()
|
||||||
|
|
||||||
|
t.startDrawing(GL11.GL_TRIANGLE_FAN)
|
||||||
|
t.addVertexWithUV(0.5, 0.03, 0.5, 0.75, 0.25)
|
||||||
|
t.addVertexWithUV(l, gb, l, 0.5, 0)
|
||||||
|
t.addVertexWithUV(h, gb, l, 1, 0)
|
||||||
|
t.addVertexWithUV(h, gb, h, 1, 0.5)
|
||||||
|
t.addVertexWithUV(l, gb, h, 0.5, 0.5)
|
||||||
|
t.addVertexWithUV(l, gb, l, 0.5, 0)
|
||||||
|
t.draw()
|
||||||
|
|
||||||
|
t.startDrawingQuads()
|
||||||
|
t.addVertexWithUV(l, gb, l, 0, 0.5)
|
||||||
|
t.addVertexWithUV(l, gb, h, 0, 1)
|
||||||
|
t.addVertexWithUV(h, gb, h, 0.5, 1)
|
||||||
|
t.addVertexWithUV(h, gb, l, 0.5, 0.5)
|
||||||
|
t.draw()
|
||||||
|
|
||||||
|
GL11.glEndList()
|
||||||
|
}
|
||||||
|
|
||||||
|
compileList()
|
||||||
|
|
||||||
|
def renderTileEntityAt(entity: TileEntity, x: Double, y: Double, z: Double, f: Float) {
|
||||||
|
val proxy = entity.asInstanceOf[tileentity.RobotProxy]
|
||||||
|
val robot = proxy.robot
|
||||||
|
val worldTime = entity.getWorldObj.getTotalWorldTime + f
|
||||||
|
|
||||||
|
{
|
||||||
|
val l = robot.world.getLightBrightnessForSkyBlocks(robot.x, robot.y, robot.z, 0)
|
||||||
|
val l1 = l % 65536
|
||||||
|
val l2 = l / 65536
|
||||||
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, l1, l2)
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glPushMatrix()
|
||||||
|
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||||
|
|
||||||
|
if (robot.isAnimatingMove) {
|
||||||
|
val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toDouble
|
||||||
|
GL11.glTranslated(
|
||||||
|
-robot.moveDirection.offsetX * remaining,
|
||||||
|
-robot.moveDirection.offsetY * remaining,
|
||||||
|
-robot.moveDirection.offsetZ * remaining)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (robot.isAnimatingTurn) {
|
||||||
|
val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toDouble
|
||||||
|
GL11.glRotated(90 * remaining, 0, robot.turnAxis, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
robot.yaw match {
|
||||||
|
case ForgeDirection.WEST => GL11.glRotatef(-90, 0, 1, 0)
|
||||||
|
case ForgeDirection.NORTH => GL11.glRotatef(180, 0, 1, 0)
|
||||||
|
case ForgeDirection.EAST => GL11.glRotatef(90, 0, 1, 0)
|
||||||
|
case _ => // No yaw.
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glTranslated(-0.5, -0.5, -0.5)
|
||||||
|
|
||||||
|
val timeJitter = robot.hashCode
|
||||||
|
val hover =
|
||||||
|
if (robot.isOn) Math.sin(timeJitter + worldTime / 20.0) * 0.03
|
||||||
|
else -0.03
|
||||||
|
GL11.glTranslated(0, hover, 0)
|
||||||
|
|
||||||
|
bindTexture(texture)
|
||||||
|
GL11.glCallList(displayList)
|
||||||
|
|
||||||
|
val size = 0.3
|
||||||
|
val l = 0.5 - size
|
||||||
|
val h = 0.5 + size
|
||||||
|
val vStep = 1.0 / 32.0
|
||||||
|
|
||||||
|
val strip = timeJitter + worldTime / 20.0
|
||||||
|
val offsetV = ((strip - strip.toInt) * 16).toInt * vStep
|
||||||
|
val (u0, u1, v0, v1) = {
|
||||||
|
if (robot.isOn)
|
||||||
|
(0.5, 1.0, 0.5 + offsetV, 0.5 + vStep + offsetV)
|
||||||
|
else
|
||||||
|
(0.25 - vStep, 0.25 + vStep, 0.75 - vStep, 0.75 + vStep)
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderState.disableLighting()
|
||||||
|
val t = Tessellator.instance
|
||||||
|
t.startDrawingQuads()
|
||||||
|
t.addVertexWithUV(l, gt, l, u0, v0)
|
||||||
|
t.addVertexWithUV(l, gb, l, u0, v1)
|
||||||
|
t.addVertexWithUV(l, gb, h, u1, v1)
|
||||||
|
t.addVertexWithUV(l, gt, h, u1, v0)
|
||||||
|
|
||||||
|
t.addVertexWithUV(l, gt, h, u0, v0)
|
||||||
|
t.addVertexWithUV(l, gb, h, u0, v1)
|
||||||
|
t.addVertexWithUV(h, gb, h, u1, v1)
|
||||||
|
t.addVertexWithUV(h, gt, h, u1, v0)
|
||||||
|
|
||||||
|
t.addVertexWithUV(h, gt, h, u0, v0)
|
||||||
|
t.addVertexWithUV(h, gb, h, u0, v1)
|
||||||
|
t.addVertexWithUV(h, gb, l, u1, v1)
|
||||||
|
t.addVertexWithUV(h, gt, l, u1, v0)
|
||||||
|
|
||||||
|
t.addVertexWithUV(h, gt, l, u0, v0)
|
||||||
|
t.addVertexWithUV(h, gb, l, u0, v1)
|
||||||
|
t.addVertexWithUV(l, gb, l, u1, v1)
|
||||||
|
t.addVertexWithUV(l, gt, l, u1, v0)
|
||||||
|
t.draw()
|
||||||
|
RenderState.enableLighting()
|
||||||
|
|
||||||
|
robot.equippedItem match {
|
||||||
|
case Some(stack) =>
|
||||||
|
GL11.glDisable(GL11.GL_CULL_FACE)
|
||||||
|
GL11.glTranslated(0.1, 0.25, 0.75)
|
||||||
|
GL11.glScaled(0.4, 0.4, -0.4)
|
||||||
|
if (robot.isAnimatingSwing) {
|
||||||
|
val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toDouble
|
||||||
|
GL11.glRotated(Math.sin(remaining * Math.PI) * 45, -1, 0, 0)
|
||||||
|
}
|
||||||
|
GL11.glRotatef(-30, 1, 0, 0)
|
||||||
|
GL11.glRotatef(40, 0, 1, 0)
|
||||||
|
try {
|
||||||
|
RenderManager.instance.itemRenderer.renderItem(robot.player(), stack, 0)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
case e: Throwable =>
|
||||||
|
OpenComputers.log.log(Level.WARNING, "Failed rendering equipped item.", e)
|
||||||
|
robot.equippedItem = None
|
||||||
|
}
|
||||||
|
GL11.glEnable(GL11.GL_CULL_FACE)
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glPopMatrix()
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,8 @@ abstract class GuiHandler extends IGuiHandler {
|
|||||||
new container.Case(player.inventory, computer)
|
new container.Case(player.inventory, computer)
|
||||||
case drive: tileentity.DiskDrive if id == GuiType.DiskDrive.id =>
|
case drive: tileentity.DiskDrive if id == GuiType.DiskDrive.id =>
|
||||||
new container.DiskDrive(player.inventory, drive)
|
new container.DiskDrive(player.inventory, drive)
|
||||||
case robot: tileentity.Robot if id == GuiType.Robot.id =>
|
case proxy: tileentity.RobotProxy if id == GuiType.Robot.id =>
|
||||||
new container.Robot(player.inventory, robot)
|
new container.Robot(player.inventory, proxy.robot)
|
||||||
case _ => null
|
case _ => null
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,8 @@ import cpw.mods.fml.common.network.Player
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import li.cil.oc.common.tileentity.TileEntity
|
import li.cil.oc.common.tileentity.TileEntity
|
||||||
import net.minecraft.nbt.NBTBase
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.{NBTTagCompound, NBTBase}
|
||||||
import net.minecraft.network.packet.Packet250CustomPayload
|
import net.minecraft.network.packet.Packet250CustomPayload
|
||||||
import net.minecraftforge.common.ForgeDirection
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
|
||||||
@ -22,10 +23,14 @@ class PacketBuilder(packetType: PacketType.Value, private val stream: ByteArrayO
|
|||||||
|
|
||||||
def writeDirection(d: ForgeDirection) = writeInt(d.ordinal)
|
def writeDirection(d: ForgeDirection) = writeInt(d.ordinal)
|
||||||
|
|
||||||
|
def writeItemStack(stack: ItemStack) = writeNBT(stack.writeToNBT(new NBTTagCompound()))
|
||||||
|
|
||||||
def writeNBT(nbt: NBTBase) = NBTBase.writeNamedTag(nbt, this)
|
def writeNBT(nbt: NBTBase) = NBTBase.writeNamedTag(nbt, this)
|
||||||
|
|
||||||
def sendToAllPlayers() = PacketDispatcher.sendPacketToAllPlayers(packet)
|
def sendToAllPlayers() = PacketDispatcher.sendPacketToAllPlayers(packet)
|
||||||
|
|
||||||
|
def sendToNearbyPlayers(t: TileEntity, range: Double = 64) = PacketDispatcher.sendPacketToAllAround(t.x, t.y, t.z, range, t.world.provider.dimensionId, packet)
|
||||||
|
|
||||||
def sendToPlayer(player: Player) = PacketDispatcher.sendPacketToPlayer(packet, player)
|
def sendToPlayer(player: Player) = PacketDispatcher.sendPacketToPlayer(packet, player)
|
||||||
|
|
||||||
def sendToServer() = PacketDispatcher.sendPacketToServer(packet)
|
def sendToServer() = PacketDispatcher.sendPacketToServer(packet)
|
||||||
|
@ -6,7 +6,8 @@ import java.io.ByteArrayInputStream
|
|||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import net.minecraft.nbt.NBTBase
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.{NBTTagCompound, NBTBase}
|
||||||
import net.minecraft.network.INetworkManager
|
import net.minecraft.network.INetworkManager
|
||||||
import net.minecraft.network.packet.Packet250CustomPayload
|
import net.minecraft.network.packet.Packet250CustomPayload
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
@ -62,6 +63,8 @@ abstract class PacketHandler extends IPacketHandler {
|
|||||||
|
|
||||||
def readDirection() = ForgeDirection.getOrientation(readInt())
|
def readDirection() = ForgeDirection.getOrientation(readInt())
|
||||||
|
|
||||||
|
def readItemStack() = ItemStack.loadItemStackFromNBT(readNBT().asInstanceOf[NBTTagCompound])
|
||||||
|
|
||||||
def readNBT() = NBTBase.readNamedTag(this)
|
def readNBT() = NBTBase.readNamedTag(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,37 +1,40 @@
|
|||||||
package li.cil.oc.common
|
package li.cil.oc.common
|
||||||
|
|
||||||
object PacketType extends Enumeration {
|
object PacketType extends Enumeration {
|
||||||
val ComputerStateRequest = Value("ComputerStateRequest")
|
val ComputerStateRequest,
|
||||||
val ComputerStateResponse = Value("ComputerStateResponse")
|
ComputerStateResponse,
|
||||||
|
|
||||||
val PowerStateRequest = Value("PowerStateRequest")
|
PowerStateRequest,
|
||||||
val PowerStateResponse = Value("PowerStateResponse")
|
PowerStateResponse,
|
||||||
|
|
||||||
val RedstoneStateRequest = Value("RedstoneStateRequest")
|
RedstoneStateRequest,
|
||||||
val RedstoneStateResponse = Value("RedstoneStateResponse")
|
RedstoneStateResponse,
|
||||||
|
|
||||||
val RobotMove = Value("RobotMove")
|
RobotAnimateSwing,
|
||||||
val RobotSelectedSlotChange = Value("RobotSelectedSlotChange")
|
RobotAnimateTurn,
|
||||||
val RobotStateRequest = Value("RobotSelectedSlotRequest")
|
RobotEquippedItemChange,
|
||||||
val RobotStateResponse = Value("RobotStateResponse")
|
RobotMove,
|
||||||
|
RobotSelectedSlotChange,
|
||||||
|
RobotStateRequest,
|
||||||
|
RobotStateResponse,
|
||||||
|
|
||||||
val RotatableStateRequest = Value("RotatableStateRequest")
|
RotatableStateRequest,
|
||||||
val RotatableStateResponse = Value("RotatableStateResponse")
|
RotatableStateResponse,
|
||||||
|
|
||||||
val ScreenBufferRequest = Value("ScreenBufferRequest")
|
ScreenBufferRequest,
|
||||||
val ScreenBufferResponse = Value("ScreenBufferResponse")
|
ScreenBufferResponse,
|
||||||
|
|
||||||
val ScreenColorChange = Value("ScreenColorChange")
|
ScreenColorChange,
|
||||||
val ScreenCopy = Value("ScreenCopy")
|
ScreenCopy,
|
||||||
val ScreenDepthChange = Value("ScreenDepthChange")
|
ScreenDepthChange,
|
||||||
val ScreenFill = Value("ScreenFill")
|
ScreenFill,
|
||||||
val ScreenPowerChange = Value("ScreenPowerChange")
|
ScreenPowerChange,
|
||||||
val ScreenResolutionChange = Value("ScreenResolutionChange")
|
ScreenResolutionChange,
|
||||||
val ScreenSet = Value("ScreenSet")
|
ScreenSet,
|
||||||
|
|
||||||
val KeyDown = Value("KeyDown")
|
KeyDown,
|
||||||
val KeyUp = Value("KeyUp")
|
KeyUp,
|
||||||
val Clipboard = Value("Clipboard")
|
Clipboard,
|
||||||
|
|
||||||
val Analyze = Value("Analyze")
|
Analyze = Value
|
||||||
}
|
}
|
@ -17,14 +17,6 @@ abstract class Computer extends Delegate {
|
|||||||
override def isProvidingWeakPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) =
|
override def isProvidingWeakPower(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) =
|
||||||
world.getBlockTileEntity(x, y, z).asInstanceOf[tileentity.Computer].output(side)
|
world.getBlockTileEntity(x, y, z).asInstanceOf[tileentity.Computer].output(side)
|
||||||
|
|
||||||
override def onBlockPreDestroy(world: World, x: Int, y: Int, z: Int) = {
|
|
||||||
if (!world.isRemote) world.getBlockTileEntity(x, y, z) match {
|
|
||||||
case computer: tileentity.Computer => computer.computer.stop()
|
|
||||||
case _ => // Ignore.
|
|
||||||
}
|
|
||||||
super.onBlockPreDestroy(world, x, y, z)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
||||||
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
|
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||||
if (!player.isSneaking) {
|
if (!player.isSneaking) {
|
||||||
|
@ -53,7 +53,7 @@ class RobotAfterimage(val parent: SpecialDelegator) extends SpecialDelegate {
|
|||||||
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
||||||
val (rx, ry, rz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
val (rx, ry, rz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||||
world.getBlockTileEntity(rx, ry, rz) match {
|
world.getBlockTileEntity(rx, ry, rz) match {
|
||||||
case robot: tileentity.Robot if robot.isAnimatingMove && robot.moveDirection == side => return Some(robot)
|
case proxy: tileentity.RobotProxy if proxy.robot.isAnimatingMove && proxy.robot.moveDirection == side => return Some(proxy.robot)
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import net.minecraft.util.{AxisAlignedBB, Vec3}
|
|||||||
import net.minecraft.world.{IBlockAccess, World}
|
import net.minecraft.world.{IBlockAccess, World}
|
||||||
import net.minecraftforge.common.ForgeDirection
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
|
||||||
class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate {
|
class RobotProxy(val parent: SpecialDelegator) extends Computer with SpecialDelegate {
|
||||||
val unlocalizedName = "Robot"
|
val unlocalizedName = "Robot"
|
||||||
|
|
||||||
var moving = new ThreadLocal[Option[tileentity.Robot]] {
|
var moving = new ThreadLocal[Option[tileentity.Robot]] {
|
||||||
@ -16,8 +16,8 @@ class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate
|
|||||||
|
|
||||||
override def createTileEntity(world: World) = {
|
override def createTileEntity(world: World) = {
|
||||||
moving.get match {
|
moving.get match {
|
||||||
case Some(robot) => Some(robot)
|
case Some(robot) => Some(new tileentity.RobotProxy(robot))
|
||||||
case _ => Some(new tileentity.Robot(world.isRemote))
|
case _ => Some(new tileentity.RobotProxy(new tileentity.Robot(world.isRemote)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,14 +35,14 @@ class Robot(val parent: SpecialDelegator) extends Computer with SpecialDelegate
|
|||||||
|
|
||||||
override def collisionRayTrace(world: World, x: Int, y: Int, z: Int, origin: Vec3, direction: Vec3) = {
|
override def collisionRayTrace(world: World, x: Int, y: Int, z: Int, origin: Vec3, direction: Vec3) = {
|
||||||
val bounds = parent.getCollisionBoundingBoxFromPool(world, x, y, z)
|
val bounds = parent.getCollisionBoundingBoxFromPool(world, x, y, z)
|
||||||
bounds.offset(x, y, z)
|
|
||||||
if (bounds.isVecInside(origin)) null
|
if (bounds.isVecInside(origin)) null
|
||||||
else super.collisionRayTrace(world, x, y, z, origin, direction)
|
else super.collisionRayTrace(world, x, y, z, origin, direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def setBlockBoundsBasedOnState(world: IBlockAccess, x: Int, y: Int, z: Int) {
|
override def setBlockBoundsBasedOnState(world: IBlockAccess, x: Int, y: Int, z: Int) {
|
||||||
world.getBlockTileEntity(x, y, z) match {
|
world.getBlockTileEntity(x, y, z) match {
|
||||||
case robot: tileentity.Robot =>
|
case proxy: tileentity.RobotProxy =>
|
||||||
|
val robot = proxy.robot
|
||||||
val bounds = AxisAlignedBB.getBoundingBox(0.1, 0.1, 0.1, 0.9, 0.9, 0.9)
|
val bounds = AxisAlignedBB.getBoundingBox(0.1, 0.1, 0.1, 0.9, 0.9, 0.9)
|
||||||
if (robot.isAnimatingMove) {
|
if (robot.isAnimatingMove) {
|
||||||
val remaining = robot.animationTicksLeft.toDouble / robot.animationTicksTotal.toDouble
|
val remaining = robot.animationTicksLeft.toDouble / robot.animationTicksTotal.toDouble
|
@ -9,11 +9,21 @@ import li.cil.oc.util.{PackedColor, Persistable}
|
|||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
trait Buffer extends Environment with Persistable {
|
trait Buffer extends Environment with Persistable {
|
||||||
val buffer = new component.Buffer(this)
|
protected val buffer_ = new component.Buffer(this)
|
||||||
|
|
||||||
var bufferIsDirty = false
|
protected var bufferIsDirty_ = false
|
||||||
|
|
||||||
var currentGui: Option[gui.Buffer] = None
|
protected var currentGui_ = None: Option[gui.Buffer]
|
||||||
|
|
||||||
|
def 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 node: Node = buffer.node
|
||||||
|
|
||||||
|
@ -11,7 +11,9 @@ import net.minecraftforge.common.ForgeDirection
|
|||||||
import scala.Some
|
import scala.Some
|
||||||
|
|
||||||
abstract class Computer(isRemote: Boolean) extends Environment with ComponentInventory with Rotatable with Redstone with Analyzable {
|
abstract class Computer(isRemote: Boolean) extends Environment with ComponentInventory with Rotatable with Redstone with Analyzable {
|
||||||
val computer = if (isRemote) null else new component.Computer(this)
|
protected val computer_ = if (isRemote) null else new component.Computer(this)
|
||||||
|
|
||||||
|
def computer = computer_
|
||||||
|
|
||||||
def node = if (isClient) null else computer.node
|
def node = if (isClient) null else computer.node
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv
|
|||||||
|
|
||||||
if (hasChanged) {
|
if (hasChanged) {
|
||||||
hasChanged = false
|
hasChanged = false
|
||||||
worldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this)
|
world.markTileEntityChunkModified(x, y, z, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRunning != computer.isRunning) {
|
if (isRunning != computer.isRunning) {
|
||||||
|
@ -23,7 +23,7 @@ abstract class Environment extends net.minecraft.tileentity.TileEntity with Tile
|
|||||||
override def updateEntity() {
|
override def updateEntity() {
|
||||||
super.updateEntity()
|
super.updateEntity()
|
||||||
if (node != null && node.network == null) {
|
if (node != null && node.network == null) {
|
||||||
Network.joinOrCreateNetwork(worldObj, xCoord, yCoord, zCoord)
|
Network.joinOrCreateNetwork(world, x, y, z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,39 +11,43 @@ import li.cil.oc.server.{PacketSender => ServerPacketSender, component}
|
|||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
import li.cil.oc.{Blocks, Config, api, common}
|
import li.cil.oc.{Blocks, Config, api, common}
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraftforge.common.ForgeDirection
|
import net.minecraftforge.common.ForgeDirection
|
||||||
import scala.Some
|
import scala.Some
|
||||||
import scala.collection.convert.WrapAsScala._
|
|
||||||
|
|
||||||
class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation {
|
class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with PowerInformation {
|
||||||
def this() = this(false)
|
def this() = this(false)
|
||||||
|
|
||||||
|
var proxy: RobotProxy = _
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override val node = api.Network.newNode(this, Visibility.Network).
|
override def node = if (isClient) null else computer.node
|
||||||
withComponent("computer", Visibility.Neighbors).
|
|
||||||
create()
|
|
||||||
|
|
||||||
override val buffer = new common.component.Buffer(this) {
|
override val buffer_ = new common.component.Buffer(this) {
|
||||||
override def maxResolution = (48, 14)
|
override def maxResolution = (48, 14)
|
||||||
}
|
}
|
||||||
override val computer = if (isRemote) null else new component.Robot(this)
|
override val computer_ = if (isRemote) null else new component.Robot(this)
|
||||||
val (battery, distributor, gpu, keyboard) = if (isServer) {
|
val (battery, distributor, gpu, keyboard) = if (isServer) {
|
||||||
val battery = api.Network.newNode(this, Visibility.Network).withConnector(10000).create()
|
val battery = api.Network.newNode(this, Visibility.Network).withConnector(10000).create()
|
||||||
val distributor = new component.PowerDistributor(this)
|
val distributor = new component.PowerDistributor(this)
|
||||||
val gpu = new GraphicsCard.Tier1 {
|
val gpu = new GraphicsCard.Tier1 {
|
||||||
override val maxResolution = (48, 14)
|
override val maxResolution = (48, 14)
|
||||||
}
|
}
|
||||||
val keyboard = new component.Keyboard(this)
|
val keyboard = new component.Keyboard(this) {
|
||||||
|
override def isUseableByPlayer(p: EntityPlayer) =
|
||||||
|
world.getBlockTileEntity(x, y, z) == proxy &&
|
||||||
|
p.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||||
|
}
|
||||||
(battery, distributor, gpu, keyboard)
|
(battery, distributor, gpu, keyboard)
|
||||||
}
|
}
|
||||||
else (null, null, null, null)
|
else (null, null, null, null)
|
||||||
|
|
||||||
var selectedSlot = 0
|
var selectedSlot = 0
|
||||||
|
|
||||||
private lazy val player_ = new Player(this)
|
var equippedItem: Option[ItemStack] = None
|
||||||
|
|
||||||
var animationTicksLeft = 0
|
var animationTicksLeft = 0
|
||||||
|
|
||||||
@ -51,12 +55,15 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
|
|
||||||
var moveDirection = ForgeDirection.UNKNOWN
|
var moveDirection = ForgeDirection.UNKNOWN
|
||||||
|
|
||||||
var turnOldFacing = ForgeDirection.UNKNOWN
|
var swingingTool = false
|
||||||
|
|
||||||
|
var turnAxis = 0
|
||||||
|
|
||||||
|
private lazy val player_ = new Player(this)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
def player(facing: ForgeDirection = facing, side: ForgeDirection = facing) = {
|
def player(facing: ForgeDirection = facing, side: ForgeDirection = facing) = {
|
||||||
assert(isServer)
|
|
||||||
player_.updatePositionAndRotation(facing, side)
|
player_.updatePositionAndRotation(facing, side)
|
||||||
player_
|
player_
|
||||||
}
|
}
|
||||||
@ -66,92 +73,107 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
def move(direction: ForgeDirection) = {
|
def move(direction: ForgeDirection) = {
|
||||||
val (ox, oy, oz) = (x, y, z)
|
val (ox, oy, oz) = (x, y, z)
|
||||||
val (nx, ny, nz) = (x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ)
|
val (nx, ny, nz) = (x + direction.offsetX, y + direction.offsetY, z + direction.offsetZ)
|
||||||
|
val blockId = world.getBlockId(nx, ny, nz)
|
||||||
|
val metadata = world.getBlockMetadata(nx, ny, nz)
|
||||||
|
try {
|
||||||
// Setting this will make the tile entity created via the following call
|
// Setting this will make the tile entity created via the following call
|
||||||
// to setBlock to re-use our "real" instance as the inner object, instead
|
// to setBlock to re-use our "real" instance as the inner object, instead
|
||||||
// of creating a new one.
|
// of creating a new one.
|
||||||
Blocks.robot.moving.set(Some(this))
|
Blocks.robotProxy.moving.set(Some(this))
|
||||||
// Do *not* immediately send the change to clients to allow checking if it
|
// Do *not* immediately send the change to clients to allow checking if it
|
||||||
// worked before the client is notified so that we can use the same trick on
|
// worked before the client is notified so that we can use the same trick on
|
||||||
// the client by sending a corresponding packet. This also saves us from
|
// the client by sending a corresponding packet. This also saves us from
|
||||||
// having to send the complete state again (e.g. screen buffer) each move.
|
// having to send the complete state again (e.g. screen buffer) each move.
|
||||||
val blockId = world.getBlockId(nx, ny, nz)
|
val created = world.setBlock(nx, ny, nz, Blocks.robotProxy.parent.blockID, Blocks.robotProxy.blockId, 1)
|
||||||
val metadata = world.getBlockMetadata(nx, ny, nz)
|
|
||||||
val created = world.setBlock(nx, ny, nz, getBlockType.blockID, getBlockMetadata, 1)
|
|
||||||
if (created) {
|
if (created) {
|
||||||
assert(world.getBlockTileEntity(nx, ny, nz) == this)
|
assert(world.getBlockTileEntity(nx, ny, nz) == proxy)
|
||||||
assert(x == nx && y == ny && z == nz)
|
assert(x == nx && y == ny && z == nz)
|
||||||
world.setBlock(ox, oy, oz, Blocks.robotAfterimage.parent.blockID, Blocks.robotAfterimage.blockId, 1)
|
world.setBlock(ox, oy, oz, Blocks.robotAfterimage.parent.blockID, Blocks.robotAfterimage.blockId, 1)
|
||||||
assert(Blocks.blockSpecial.subBlock(world, ox, oy, oz).exists(_ == Blocks.robotAfterimage))
|
assert(Blocks.blockSpecial.subBlock(world, ox, oy, oz).exists(_ == Blocks.robotAfterimage))
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
ServerPacketSender.sendRobotMove(this, ox, oy, oz, direction)
|
ServerPacketSender.sendRobotMove(this, ox, oy, oz, direction)
|
||||||
for (neighbor <- node.neighbors) {
|
|
||||||
node.disconnect(neighbor)
|
|
||||||
}
|
|
||||||
api.Network.joinOrCreateNetwork(world, nx, ny, nz)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// On the client this is called from the packet handler code, leading
|
// If we broke some replaceable block (like grass) play its break sound.
|
||||||
// to the entity being added directly to the list of loaded tile
|
|
||||||
// entities, without any additional checks - so we get a duplicate.
|
|
||||||
val duplicate = world.loadedTileEntityList.remove(world.loadedTileEntityList.size - 1)
|
|
||||||
assert(duplicate == this)
|
|
||||||
if (blockId > 0) {
|
if (blockId > 0) {
|
||||||
world.playAuxSFX(2001, nx, ny, nz, blockId + (metadata << 12))
|
world.playAuxSFX(2001, nx, ny, nz, blockId + (metadata << 12))
|
||||||
}
|
}
|
||||||
world.markBlockForUpdate(ox, oy, oz)
|
world.markBlockForRenderUpdate(ox, oy, oz)
|
||||||
world.markBlockForUpdate(nx, ny, nz)
|
world.markBlockForRenderUpdate(nx, ny, nz)
|
||||||
}
|
}
|
||||||
assert(!isInvalid)
|
assert(!isInvalid)
|
||||||
}
|
}
|
||||||
Blocks.robot.moving.set(None)
|
|
||||||
if (created) {
|
if (created) {
|
||||||
|
// Here instead of Lua callback so that it gets triggered on client.
|
||||||
animateMove(direction, Config.moveDelay)
|
animateMove(direction, Config.moveDelay)
|
||||||
checkRedstoneInputChanged()
|
checkRedstoneInputChanged()
|
||||||
}
|
}
|
||||||
created
|
created
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
Blocks.robotProxy.moving.set(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def isAnimatingMove = animationTicksLeft > 0 && moveDirection != ForgeDirection.UNKNOWN
|
def isAnimatingMove = animationTicksLeft > 0 && moveDirection != ForgeDirection.UNKNOWN
|
||||||
|
|
||||||
def isAnimatingTurn = animationTicksLeft > 0 && turnOldFacing != ForgeDirection.UNKNOWN
|
def isAnimatingSwing = animationTicksLeft > 0 && swingingTool
|
||||||
|
|
||||||
def animateMove(direction: ForgeDirection, duration: Double) {
|
def isAnimatingTurn = animationTicksLeft > 0 && turnAxis != 0
|
||||||
animationTicksTotal = (duration * 20).toInt
|
|
||||||
animationTicksLeft = animationTicksTotal
|
def animateMove(direction: ForgeDirection, duration: Double) =
|
||||||
moveDirection = direction
|
setAnimateMove(direction, (duration * 20).toInt)
|
||||||
turnOldFacing = ForgeDirection.UNKNOWN
|
|
||||||
|
def animateSwing(duration: Double) = {
|
||||||
|
setAnimateSwing((duration * 20).toInt)
|
||||||
|
ServerPacketSender.sendRobotAnimateSwing(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
def animateTurn(oldFacing: ForgeDirection, duration: Double) {
|
def animateTurn(clockwise: Boolean, duration: Double) = {
|
||||||
animationTicksTotal = (duration * 20).toInt
|
setAnimateTurn(if (clockwise) 1 else -1, (duration * 20).toInt)
|
||||||
|
ServerPacketSender.sendRobotAnimateTurn(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
def setAnimateMove(direction: ForgeDirection, ticks: Int) {
|
||||||
|
animationTicksTotal = ticks
|
||||||
|
prepareForAnimation()
|
||||||
|
moveDirection = direction
|
||||||
|
}
|
||||||
|
|
||||||
|
def setAnimateSwing(ticks: Int) {
|
||||||
|
animationTicksTotal = ticks
|
||||||
|
prepareForAnimation()
|
||||||
|
swingingTool = true
|
||||||
|
}
|
||||||
|
|
||||||
|
def setAnimateTurn(axis: Int, ticks: Int) {
|
||||||
|
animationTicksTotal = ticks
|
||||||
|
prepareForAnimation()
|
||||||
|
turnAxis = axis
|
||||||
|
}
|
||||||
|
|
||||||
|
private def prepareForAnimation() {
|
||||||
animationTicksLeft = animationTicksTotal
|
animationTicksLeft = animationTicksTotal
|
||||||
moveDirection = ForgeDirection.UNKNOWN
|
moveDirection = ForgeDirection.UNKNOWN
|
||||||
turnOldFacing = oldFacing
|
swingingTool = false
|
||||||
|
turnAxis = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def getRenderBoundingBox =
|
||||||
|
getBlockType.getCollisionBoundingBoxFromPool(world, x, y, z).expand(0.5, 0.5, 0.5)
|
||||||
|
|
||||||
override def installedMemory = 64 * 1024
|
override def installedMemory = 64 * 1024
|
||||||
|
|
||||||
def tier = 0
|
def tier = 0
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
@LuaCallback("start")
|
|
||||||
def start(context: Context, args: Arguments): Array[AnyRef] =
|
|
||||||
result(computer.start())
|
|
||||||
|
|
||||||
@LuaCallback("stop")
|
|
||||||
def stop(context: Context, args: Arguments): Array[AnyRef] =
|
|
||||||
result(computer.stop())
|
|
||||||
|
|
||||||
@LuaCallback(value = "isRunning", direct = true)
|
|
||||||
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
|
|
||||||
result(computer.isRunning)
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
|
||||||
|
|
||||||
override def updateEntity() {
|
override def updateEntity() {
|
||||||
|
if (node != null && node.network == null) {
|
||||||
|
api.Network.joinNewNetwork(computer.node)
|
||||||
|
}
|
||||||
if (animationTicksLeft > 0) {
|
if (animationTicksLeft > 0) {
|
||||||
animationTicksLeft -= 1
|
animationTicksLeft -= 1
|
||||||
if (animationTicksLeft == 0) {
|
if (animationTicksLeft == 0) {
|
||||||
@ -173,7 +195,6 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
}
|
}
|
||||||
|
|
||||||
override def validate() {
|
override def validate() {
|
||||||
if (Blocks.robot.moving.get.isEmpty) {
|
|
||||||
super.validate()
|
super.validate()
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
items(0) match {
|
items(0) match {
|
||||||
@ -186,21 +207,17 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
ClientPacketSender.sendRobotStateRequest(this)
|
ClientPacketSender.sendRobotStateRequest(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override def invalidate() {
|
override def invalidate() {
|
||||||
if (Blocks.robot.moving.get.isEmpty) {
|
|
||||||
super.invalidate()
|
super.invalidate()
|
||||||
if (currentGui.isDefined) {
|
if (currentGui.isDefined) {
|
||||||
Minecraft.getMinecraft.displayGuiScreen(null)
|
Minecraft.getMinecraft.displayGuiScreen(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def readFromNBT(nbt: NBTTagCompound) {
|
override def readFromNBT(nbt: NBTTagCompound) {
|
||||||
super.readFromNBT(nbt)
|
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
battery.load(nbt.getCompoundTag(Config.namespace + "battery"))
|
battery.load(nbt.getCompoundTag(Config.namespace + "battery"))
|
||||||
buffer.load(nbt.getCompoundTag(Config.namespace + "buffer"))
|
buffer.load(nbt.getCompoundTag(Config.namespace + "buffer"))
|
||||||
@ -211,12 +228,14 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
selectedSlot = nbt.getInteger(Config.namespace + "selectedSlot")
|
selectedSlot = nbt.getInteger(Config.namespace + "selectedSlot")
|
||||||
animationTicksTotal = nbt.getInteger(Config.namespace + "animationTicksTotal")
|
animationTicksTotal = nbt.getInteger(Config.namespace + "animationTicksTotal")
|
||||||
animationTicksLeft = nbt.getInteger(Config.namespace + "animationTicksLeft")
|
animationTicksLeft = nbt.getInteger(Config.namespace + "animationTicksLeft")
|
||||||
moveDirection = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "moveDirection"))
|
if (animationTicksLeft > 0) {
|
||||||
turnOldFacing = ForgeDirection.getOrientation(nbt.getInteger(Config.namespace + "turnOldFacing"))
|
moveDirection = ForgeDirection.getOrientation(nbt.getByte(Config.namespace + "moveDirection"))
|
||||||
|
swingingTool = nbt.getBoolean(Config.namespace + "swingingTool")
|
||||||
|
turnAxis = nbt.getByte(Config.namespace + "turnAxis")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def writeToNBT(nbt: NBTTagCompound) {
|
override def writeToNBT(nbt: NBTTagCompound) {
|
||||||
super.writeToNBT(nbt)
|
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
nbt.setNewCompoundTag(Config.namespace + "battery", battery.save)
|
nbt.setNewCompoundTag(Config.namespace + "battery", battery.save)
|
||||||
nbt.setNewCompoundTag(Config.namespace + "buffer", buffer.save)
|
nbt.setNewCompoundTag(Config.namespace + "buffer", buffer.save)
|
||||||
@ -225,27 +244,26 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
nbt.setNewCompoundTag(Config.namespace + "keyboard", keyboard.save)
|
nbt.setNewCompoundTag(Config.namespace + "keyboard", keyboard.save)
|
||||||
}
|
}
|
||||||
nbt.setInteger(Config.namespace + "selectedSlot", selectedSlot)
|
nbt.setInteger(Config.namespace + "selectedSlot", selectedSlot)
|
||||||
if (isAnimatingMove || isAnimatingTurn) {
|
if (isAnimatingMove || isAnimatingSwing || isAnimatingTurn) {
|
||||||
nbt.setInteger(Config.namespace + "animationTicksTotal", animationTicksTotal)
|
nbt.setInteger(Config.namespace + "animationTicksTotal", animationTicksTotal)
|
||||||
nbt.setInteger(Config.namespace + "animationTicksLeft", animationTicksLeft)
|
nbt.setInteger(Config.namespace + "animationTicksLeft", animationTicksLeft)
|
||||||
nbt.setInteger(Config.namespace + "moveDirection", moveDirection.ordinal)
|
nbt.setByte(Config.namespace + "moveDirection", moveDirection.ordinal.toByte)
|
||||||
nbt.setInteger(Config.namespace + "turnOldFacing", turnOldFacing.ordinal)
|
nbt.setBoolean(Config.namespace + "swingingTool", swingingTool)
|
||||||
|
nbt.setByte(Config.namespace + "turnAxis", turnAxis.toByte)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
override def onConnect(node: Node) {
|
override def onConnect(node: Node) {
|
||||||
|
super.onConnect(node)
|
||||||
if (node == this.node) {
|
if (node == this.node) {
|
||||||
api.Network.joinNewNetwork(computer.node)
|
|
||||||
|
|
||||||
computer.node.connect(buffer.node)
|
computer.node.connect(buffer.node)
|
||||||
computer.node.connect(distributor.node)
|
computer.node.connect(distributor.node)
|
||||||
computer.node.connect(gpu.node)
|
computer.node.connect(gpu.node)
|
||||||
distributor.node.connect(battery)
|
distributor.node.connect(battery)
|
||||||
buffer.node.connect(keyboard.node)
|
buffer.node.connect(keyboard.node)
|
||||||
}
|
}
|
||||||
super.onConnect(node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onDisconnect(node: Node) {
|
override def onDisconnect(node: Node) {
|
||||||
@ -280,6 +298,12 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
|
|
||||||
override def getInventoryStackLimit = 64
|
override def getInventoryStackLimit = 64
|
||||||
|
|
||||||
|
override def isUseableByPlayer(player: EntityPlayer) =
|
||||||
|
world.getBlockTileEntity(x, y, z) match {
|
||||||
|
case t: RobotProxy if t == proxy => player.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
|
||||||
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
def isItemValidForSlot(slot: Int, item: ItemStack) = (slot, Registry.driverFor(item)) match {
|
||||||
case (0, _) => true // Allow anything in the tool slot.
|
case (0, _) => true // Allow anything in the tool slot.
|
||||||
case (1, Some(driver)) => driver.slot(item) == Slot.Card
|
case (1, Some(driver)) => driver.slot(item) == Slot.Card
|
||||||
@ -288,19 +312,38 @@ class Robot(isRemote: Boolean) extends Computer(isRemote) with Buffer with Power
|
|||||||
case _ => false // Invalid slot.
|
case _ => false // Invalid slot.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def onInventoryChanged() {
|
||||||
|
super.onInventoryChanged()
|
||||||
|
if (isServer) {
|
||||||
|
computer.signal("inventory_changed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override protected def onItemRemoved(slot: Int, item: ItemStack) {
|
override protected def onItemRemoved(slot: Int, item: ItemStack) {
|
||||||
super.onItemRemoved(slot, item)
|
super.onItemRemoved(slot, item)
|
||||||
|
if (isServer) {
|
||||||
if (slot == 0) {
|
if (slot == 0) {
|
||||||
player_.getAttributeMap.removeAttributeModifiers(item.getAttributeModifiers)
|
player_.getAttributeMap.removeAttributeModifiers(item.getAttributeModifiers)
|
||||||
|
ServerPacketSender.sendRobotEquippedItemChange(this)
|
||||||
|
}
|
||||||
|
else if (slot >= actualSlot(0)) {
|
||||||
|
computer.signal("inventory_changed", Int.box(slot - actualSlot(0) + 1))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override protected def onItemAdded(slot: Int, item: ItemStack) {
|
override protected def onItemAdded(slot: Int, item: ItemStack) {
|
||||||
|
if (isServer) {
|
||||||
if (slot == 0) {
|
if (slot == 0) {
|
||||||
player_.getAttributeMap.applyAttributeModifiers(item.getAttributeModifiers)
|
player_.getAttributeMap.applyAttributeModifiers(item.getAttributeModifiers)
|
||||||
|
ServerPacketSender.sendRobotEquippedItemChange(this)
|
||||||
}
|
}
|
||||||
else if (slot == 1 || slot == 2) {
|
else if (slot == 1 || slot == 2) {
|
||||||
super.onItemAdded(slot, item)
|
super.onItemAdded(slot, item)
|
||||||
}
|
}
|
||||||
|
else if (slot >= actualSlot(0)) {
|
||||||
|
computer.signal("inventory_changed", Int.box(slot - actualSlot(0) + 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
229
li/cil/oc/common/tileentity/RobotProxy.scala
Normal file
229
li/cil/oc/common/tileentity/RobotProxy.scala
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
package li.cil.oc.common.tileentity
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.Optional
|
||||||
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.network._
|
||||||
|
import li.cil.oc.client.gui
|
||||||
|
import mods.immibis.redlogic.api.wiring.IWire
|
||||||
|
import net.minecraft.entity.Entity
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.minecraftforge.common.ForgeDirection
|
||||||
|
|
||||||
|
class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with Buffer with PowerInformation {
|
||||||
|
def this() = this(new Robot(false))
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
@LuaCallback("start")
|
||||||
|
def start(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
|
result(computer.start())
|
||||||
|
|
||||||
|
@LuaCallback("stop")
|
||||||
|
def stop(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
|
result(computer.stop())
|
||||||
|
|
||||||
|
@LuaCallback(value = "isRunning", direct = true)
|
||||||
|
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
|
result(computer.isRunning)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = robot.onAnalyze(stats, player, side, hitX, hitY, hitZ)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override val node = api.Network.newNode(this, Visibility.Network).
|
||||||
|
withComponent("computer", Visibility.Neighbors).
|
||||||
|
create()
|
||||||
|
|
||||||
|
override def isClient = robot.isClient
|
||||||
|
|
||||||
|
override def isServer = robot.isServer
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def isOutputEnabled = robot.isOutputEnabled
|
||||||
|
|
||||||
|
override def isOutputEnabled_=(value: Boolean) = robot.isOutputEnabled_=(value)
|
||||||
|
|
||||||
|
override def input(side: ForgeDirection) = robot.input(side)
|
||||||
|
|
||||||
|
override def output(side: ForgeDirection) = robot.output(side)
|
||||||
|
|
||||||
|
override def output(side: ForgeDirection, value: Short) = robot.output(side, value)
|
||||||
|
|
||||||
|
override def bundledInput(side: ForgeDirection, color: Int) = robot.bundledInput(side, color)
|
||||||
|
|
||||||
|
override def bundledOutput(side: ForgeDirection, color: Int) = robot.bundledOutput(side, color)
|
||||||
|
|
||||||
|
override def bundledOutput(side: ForgeDirection, color: Int, value: Short) = robot.bundledOutput(side, color, value)
|
||||||
|
|
||||||
|
override def checkRedstoneInputChanged() = robot.checkRedstoneInputChanged()
|
||||||
|
|
||||||
|
override def updateRedstoneInput() = robot.updateRedstoneInput()
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def connects(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connects(wire, blockFace, fromDirection)
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def connectsAroundCorner(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connectsAroundCorner(wire, blockFace, fromDirection)
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def getBundledCableStrength(blockFace: Int, toDirection: Int) = robot.getBundledCableStrength(blockFace, toDirection)
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def getEmittedSignalStrength(blockFace: Int, toDirection: Int) = robot.getEmittedSignalStrength(blockFace, toDirection)
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def onBundledInputChanged() = robot.onBundledInputChanged()
|
||||||
|
|
||||||
|
@Optional.Method(modid = "RedLogic")
|
||||||
|
override def onRedstoneInputChanged() = robot.onRedstoneInputChanged()
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def pitch = robot.pitch
|
||||||
|
|
||||||
|
override def pitch_=(value: ForgeDirection) = robot.pitch_=(value)
|
||||||
|
|
||||||
|
override def yaw = robot.yaw
|
||||||
|
|
||||||
|
override def yaw_=(value: ForgeDirection) = robot.yaw_=(value)
|
||||||
|
|
||||||
|
override def setFromEntityPitchAndYaw(entity: Entity) = robot.setFromEntityPitchAndYaw(entity)
|
||||||
|
|
||||||
|
override def setFromFacing(value: ForgeDirection) = robot.setFromFacing(value)
|
||||||
|
|
||||||
|
override def invertRotation() = robot.invertRotation()
|
||||||
|
|
||||||
|
override def facing = robot.facing
|
||||||
|
|
||||||
|
override def rotate(axis: ForgeDirection) = robot.rotate(axis)
|
||||||
|
|
||||||
|
override def toLocal(value: ForgeDirection) = robot.toLocal(value)
|
||||||
|
|
||||||
|
override def toGlobal(value: ForgeDirection) = robot.toGlobal(value)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def getStackInSlot(i: Int) = robot.getStackInSlot(i)
|
||||||
|
|
||||||
|
override def decrStackSize(slot: Int, amount: Int) = robot.decrStackSize(slot, amount)
|
||||||
|
|
||||||
|
override def setInventorySlotContents(slot: Int, item: ItemStack) = robot.setInventorySlotContents(slot, item)
|
||||||
|
|
||||||
|
override def getStackInSlotOnClosing(slot: Int) = robot.getStackInSlotOnClosing(slot)
|
||||||
|
|
||||||
|
override def openChest() = robot.openChest()
|
||||||
|
|
||||||
|
override def closeChest() = robot.closeChest()
|
||||||
|
|
||||||
|
override def isInvNameLocalized = robot.isInvNameLocalized
|
||||||
|
|
||||||
|
override def isUseableByPlayer(player: EntityPlayer) = robot.isUseableByPlayer(player)
|
||||||
|
|
||||||
|
override def dropSlot(slot: Int, count: Int, direction: ForgeDirection) = robot.dropSlot(slot, count, direction)
|
||||||
|
|
||||||
|
override def dropAllSlots() = robot.dropAllSlots()
|
||||||
|
|
||||||
|
override def getInventoryStackLimit = robot.getInventoryStackLimit
|
||||||
|
|
||||||
|
override def installedMemory = robot.installedMemory
|
||||||
|
|
||||||
|
def getInvName = robot.getInvName
|
||||||
|
|
||||||
|
def getSizeInventory = robot.getSizeInventory
|
||||||
|
|
||||||
|
def isItemValidForSlot(slot: Int, stack: ItemStack) = robot.isItemValidForSlot(slot, stack)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def canUpdate = robot.canUpdate
|
||||||
|
|
||||||
|
override def updateEntity() = robot.updateEntity()
|
||||||
|
|
||||||
|
override def validate() {
|
||||||
|
super.validate()
|
||||||
|
val firstProxy = robot.proxy == null
|
||||||
|
robot.proxy = this
|
||||||
|
robot.worldObj = worldObj
|
||||||
|
robot.xCoord = xCoord
|
||||||
|
robot.yCoord = yCoord
|
||||||
|
robot.zCoord = zCoord
|
||||||
|
if (firstProxy) {
|
||||||
|
robot.validate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def invalidate() {
|
||||||
|
super.invalidate()
|
||||||
|
if (robot.proxy == this) {
|
||||||
|
robot.invalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def onChunkUnload() {
|
||||||
|
super.onChunkUnload()
|
||||||
|
if (robot.proxy == this) {
|
||||||
|
robot.onChunkUnload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def readFromNBT(nbt: NBTTagCompound) {
|
||||||
|
super.readFromNBT(nbt)
|
||||||
|
robot.readFromNBT(nbt)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def writeToNBT(nbt: NBTTagCompound) {
|
||||||
|
super.writeToNBT(nbt)
|
||||||
|
robot.writeToNBT(nbt)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def save(nbt: NBTTagCompound) = robot.save(nbt)
|
||||||
|
|
||||||
|
override def load(nbt: NBTTagCompound) = robot.load(nbt)
|
||||||
|
|
||||||
|
override def getMaxRenderDistanceSquared = robot.getMaxRenderDistanceSquared
|
||||||
|
|
||||||
|
override def getRenderBoundingBox = robot.getRenderBoundingBox
|
||||||
|
|
||||||
|
override def shouldRenderInPass(pass: Int) = robot.shouldRenderInPass(pass)
|
||||||
|
|
||||||
|
override def onInventoryChanged() = robot.onInventoryChanged()
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def onMessage(message: Message) = robot.onMessage(message)
|
||||||
|
|
||||||
|
override def onConnect(node: Node) = robot.onConnect(node)
|
||||||
|
|
||||||
|
override def onDisconnect(node: Node) = robot.onDisconnect(node)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def computer = robot.computer
|
||||||
|
|
||||||
|
override def isOn = robot.isOn
|
||||||
|
|
||||||
|
override def isOn_=(value: Boolean) = robot.isOn_=(value)
|
||||||
|
|
||||||
|
override def markAsChanged() = robot.markAsChanged()
|
||||||
|
|
||||||
|
override def hasRedstoneCard = robot.hasRedstoneCard
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
override def buffer = robot.buffer
|
||||||
|
|
||||||
|
override def bufferIsDirty = robot.bufferIsDirty
|
||||||
|
|
||||||
|
override def bufferIsDirty_=(value: Boolean) = robot.bufferIsDirty = value
|
||||||
|
|
||||||
|
override def currentGui = robot.currentGui
|
||||||
|
|
||||||
|
override def currentGui_=(value: Option[gui.Buffer]) = robot.currentGui = value
|
||||||
|
|
||||||
|
def tier = robot.tier
|
||||||
|
}
|
@ -154,9 +154,9 @@ class Screen(var tier: Int) extends Buffer with Rotatable with Analyzable with O
|
|||||||
if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox
|
if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox
|
||||||
else {
|
else {
|
||||||
val (sx, sy, sz) = unproject(width, height, 1)
|
val (sx, sy, sz) = unproject(width, height, 1)
|
||||||
val ox = xCoord + (if (sx < 0) 1 else 0)
|
val ox = x + (if (sx < 0) 1 else 0)
|
||||||
val oy = yCoord + (if (sy < 0) 1 else 0)
|
val oy = y + (if (sy < 0) 1 else 0)
|
||||||
val oz = zCoord + (if (sz < 0) 1 else 0)
|
val oz = z + (if (sz < 0) 1 else 0)
|
||||||
val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz)
|
val b = AxisAlignedBB.getAABBPool.getAABB(ox, oy, oz, ox + sx, oy + sy, oz + sz)
|
||||||
b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ,
|
b.setBounds(b.minX min b.maxX, b.minY min b.maxY, b.minZ min b.maxZ,
|
||||||
b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ)
|
b.minX max b.maxX, b.minY max b.maxY, b.minZ max b.maxZ)
|
||||||
@ -227,7 +227,7 @@ class Screen(var tier: Int) extends Buffer with Rotatable with Analyzable with O
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def project(t: Screen) = {
|
private def project(t: Screen) = {
|
||||||
def dot(f: ForgeDirection, s: Screen) = f.offsetX * s.xCoord + f.offsetY * s.yCoord + f.offsetZ * s.zCoord
|
def dot(f: ForgeDirection, s: Screen) = f.offsetX * s.x + f.offsetY * s.y + f.offsetZ * s.z
|
||||||
(dot(toGlobal(ForgeDirection.EAST), t), dot(toGlobal(ForgeDirection.UP), t), dot(toGlobal(ForgeDirection.SOUTH), t))
|
(dot(toGlobal(ForgeDirection.EAST), t), dot(toGlobal(ForgeDirection.UP), t), dot(toGlobal(ForgeDirection.SOUTH), t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
case PacketType.ComputerStateRequest => onComputerStateRequest(p)
|
case PacketType.ComputerStateRequest => onComputerStateRequest(p)
|
||||||
case PacketType.PowerStateRequest => onPowerStateRequest(p)
|
case PacketType.PowerStateRequest => onPowerStateRequest(p)
|
||||||
case PacketType.RedstoneStateRequest => onRedstoneStateRequest(p)
|
case PacketType.RedstoneStateRequest => onRedstoneStateRequest(p)
|
||||||
case PacketType.RobotStateRequest => onRobotSelectedSlotRequest(p)
|
case PacketType.RobotStateRequest => onRobotStateRequest(p)
|
||||||
case PacketType.RotatableStateRequest => onRotatableStateRequest(p)
|
case PacketType.RotatableStateRequest => onRotatableStateRequest(p)
|
||||||
case PacketType.ScreenBufferRequest => onScreenBufferRequest(p)
|
case PacketType.ScreenBufferRequest => onScreenBufferRequest(p)
|
||||||
case PacketType.KeyDown => onKeyDown(p)
|
case PacketType.KeyDown => onKeyDown(p)
|
||||||
@ -43,9 +43,9 @@ class PacketHandler extends CommonPacketHandler {
|
|||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
def onRobotSelectedSlotRequest(p: PacketParser) =
|
def onRobotStateRequest(p: PacketParser) =
|
||||||
p.readTileEntity[Robot]() match {
|
p.readTileEntity[RobotProxy]() match {
|
||||||
case Some(t) => PacketSender.sendRobotSelectedSlotChange(t, Option(p.player))
|
case Some(t) => PacketSender.sendRobotState(t.robot, Option(p.player))
|
||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ object PacketSender {
|
|||||||
val pb = new PacketBuilder(PacketType.RobotMove)
|
val pb = new PacketBuilder(PacketType.RobotMove)
|
||||||
|
|
||||||
// Custom pb.writeTileEntity() with fake coordinates (valid for the client).
|
// Custom pb.writeTileEntity() with fake coordinates (valid for the client).
|
||||||
pb.writeInt(t.world.provider.dimensionId)
|
pb.writeInt(t.proxy.world.provider.dimensionId)
|
||||||
pb.writeInt(ox)
|
pb.writeInt(ox)
|
||||||
pb.writeInt(oy)
|
pb.writeInt(oy)
|
||||||
pb.writeInt(oz)
|
pb.writeInt(oz)
|
||||||
@ -72,27 +72,54 @@ object PacketSender {
|
|||||||
pb.sendToAllPlayers()
|
pb.sendToAllPlayers()
|
||||||
}
|
}
|
||||||
|
|
||||||
def sendRobotSelectedSlotChange(t: Robot, player: Option[Player] = None) {
|
def sendRobotAnimateSwing(t: Robot) {
|
||||||
|
val pb = new PacketBuilder(PacketType.RobotAnimateSwing)
|
||||||
|
|
||||||
|
pb.writeTileEntity(t.proxy)
|
||||||
|
pb.writeInt(t.animationTicksTotal)
|
||||||
|
|
||||||
|
pb.sendToNearbyPlayers(t.proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendRobotAnimateTurn(t: Robot) {
|
||||||
|
val pb = new PacketBuilder(PacketType.RobotAnimateTurn)
|
||||||
|
|
||||||
|
pb.writeTileEntity(t.proxy)
|
||||||
|
pb.writeByte(t.turnAxis)
|
||||||
|
pb.writeInt(t.animationTicksTotal)
|
||||||
|
|
||||||
|
pb.sendToNearbyPlayers(t.proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendRobotEquippedItemChange(t: Robot) {
|
||||||
|
val pb = new PacketBuilder(PacketType.RobotEquippedItemChange)
|
||||||
|
|
||||||
|
pb.writeTileEntity(t.proxy)
|
||||||
|
pb.writeItemStack(t.getStackInSlot(0))
|
||||||
|
|
||||||
|
pb.sendToAllPlayers()
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendRobotSelectedSlotChange(t: Robot) {
|
||||||
val pb = new PacketBuilder(PacketType.RobotSelectedSlotChange)
|
val pb = new PacketBuilder(PacketType.RobotSelectedSlotChange)
|
||||||
|
|
||||||
pb.writeTileEntity(t)
|
pb.writeTileEntity(t.proxy)
|
||||||
pb.writeInt(t.selectedSlot)
|
pb.writeInt(t.selectedSlot)
|
||||||
|
|
||||||
player match {
|
pb.sendToAllPlayers()
|
||||||
case Some(p) => pb.sendToPlayer(p)
|
|
||||||
case _ => pb.sendToAllPlayers()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def sendRobotState(t: Robot, player: Option[Player] = None) {
|
def sendRobotState(t: Robot, player: Option[Player] = None) {
|
||||||
val pb = new PacketBuilder(PacketType.RobotStateResponse)
|
val pb = new PacketBuilder(PacketType.RobotStateResponse)
|
||||||
|
|
||||||
pb.writeTileEntity(t)
|
pb.writeTileEntity(t.proxy)
|
||||||
pb.writeInt(t.selectedSlot)
|
pb.writeInt(t.selectedSlot)
|
||||||
|
pb.writeItemStack(t.getStackInSlot(0))
|
||||||
pb.writeInt(t.animationTicksTotal)
|
pb.writeInt(t.animationTicksTotal)
|
||||||
pb.writeInt(t.animationTicksLeft)
|
pb.writeInt(t.animationTicksLeft)
|
||||||
pb.writeDirection(t.moveDirection)
|
pb.writeDirection(t.moveDirection)
|
||||||
pb.writeDirection(t.turnOldFacing)
|
pb.writeBoolean(t.swingingTool)
|
||||||
|
pb.writeByte(t.turnAxis)
|
||||||
|
|
||||||
player match {
|
player match {
|
||||||
case Some(p) => pb.sendToPlayer(p)
|
case Some(p) => pb.sendToPlayer(p)
|
||||||
|
@ -69,7 +69,7 @@ class Keyboard(owner: Environment) extends ManagedComponent {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
private def isUseableByPlayer(p: EntityPlayer) =
|
def isUseableByPlayer(p: EntityPlayer) =
|
||||||
owner.world.getBlockTileEntity(owner.x, owner.y, owner.z) == owner &&
|
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
|
p.getDistanceSq(owner.x + 0.5, owner.y + 0.5, owner.z + 0.5) <= 64
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
}
|
}
|
||||||
if (what) {
|
if (what) {
|
||||||
context.pause(Config.placeDelay)
|
context.pause(Config.placeDelay)
|
||||||
|
robot.animateSwing(Config.placeDelay)
|
||||||
}
|
}
|
||||||
result(what)
|
result(what)
|
||||||
}
|
}
|
||||||
@ -207,17 +208,21 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
throw new IllegalArgumentException("invalid side")
|
throw new IllegalArgumentException("invalid side")
|
||||||
}
|
}
|
||||||
val player = robot.player(facing, side)
|
val player = robot.player(facing, side)
|
||||||
|
def triggerDelay() = {
|
||||||
|
context.pause(Config.swingDelay)
|
||||||
|
robot.animateSwing(Config.swingDelay)
|
||||||
|
}
|
||||||
Option(pick(facing, side, Config.swingRange)) match {
|
Option(pick(facing, side, Config.swingRange)) match {
|
||||||
case Some(hit) =>
|
case Some(hit) =>
|
||||||
val what = hit.typeOfHit match {
|
val what = hit.typeOfHit match {
|
||||||
case EnumMovingObjectType.ENTITY =>
|
case EnumMovingObjectType.ENTITY =>
|
||||||
player.attackTargetEntityWithCurrentItem(hit.entityHit)
|
player.attackTargetEntityWithCurrentItem(hit.entityHit)
|
||||||
context.pause(Config.swingDelay)
|
triggerDelay()
|
||||||
result(true, "entity")
|
result(true, "entity")
|
||||||
case EnumMovingObjectType.TILE =>
|
case EnumMovingObjectType.TILE =>
|
||||||
val broke = player.clickBlock(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
val broke = player.clickBlock(hit.blockX, hit.blockY, hit.blockZ, hit.sideHit)
|
||||||
if (broke) {
|
if (broke) {
|
||||||
context.pause(Config.swingDelay)
|
triggerDelay()
|
||||||
}
|
}
|
||||||
result(broke, "block")
|
result(broke, "block")
|
||||||
}
|
}
|
||||||
@ -226,7 +231,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
player.closestLivingEntity(facing) match {
|
player.closestLivingEntity(facing) match {
|
||||||
case Some(entity) =>
|
case Some(entity) =>
|
||||||
player.attackTargetEntityWithCurrentItem(entity)
|
player.attackTargetEntityWithCurrentItem(entity)
|
||||||
context.pause(Config.swingDelay)
|
triggerDelay()
|
||||||
result(true, "entity")
|
result(true, "entity")
|
||||||
case _ =>
|
case _ =>
|
||||||
result(false)
|
result(false)
|
||||||
@ -243,16 +248,20 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
}
|
}
|
||||||
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
|
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
|
||||||
val player = robot.player(facing, side)
|
val player = robot.player(facing, side)
|
||||||
|
def triggerDelay() {
|
||||||
|
context.pause(Config.useDelay)
|
||||||
|
robot.animateSwing(Config.useDelay)
|
||||||
|
}
|
||||||
def activationResult(activationType: ActivationType.Value): Array[AnyRef] =
|
def activationResult(activationType: ActivationType.Value): Array[AnyRef] =
|
||||||
activationType match {
|
activationType match {
|
||||||
case ActivationType.BlockActivated =>
|
case ActivationType.BlockActivated =>
|
||||||
context.pause(Config.useDelay)
|
triggerDelay()
|
||||||
result(true, "block_activated")
|
result(true, "block_activated")
|
||||||
case ActivationType.ItemPlaced =>
|
case ActivationType.ItemPlaced =>
|
||||||
context.pause(Config.useDelay)
|
triggerDelay()
|
||||||
result(true, "item_placed")
|
result(true, "item_placed")
|
||||||
case ActivationType.ItemUsed =>
|
case ActivationType.ItemUsed =>
|
||||||
context.pause(Config.useDelay)
|
triggerDelay()
|
||||||
result(true, "item_used")
|
result(true, "item_used")
|
||||||
case _ => result(false)
|
case _ => result(false)
|
||||||
}
|
}
|
||||||
@ -275,7 +284,7 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
} else ActivationType.None) match {
|
} else ActivationType.None) match {
|
||||||
case ActivationType.None =>
|
case ActivationType.None =>
|
||||||
if (player.useEquippedItem()) {
|
if (player.useEquippedItem()) {
|
||||||
context.pause(Config.useDelay)
|
triggerDelay()
|
||||||
result(true, "item_used")
|
result(true, "item_used")
|
||||||
}
|
}
|
||||||
else result(false)
|
else result(false)
|
||||||
@ -321,10 +330,9 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
|
|||||||
@LuaCallback("turn")
|
@LuaCallback("turn")
|
||||||
def turn(context: Context, args: Arguments): Array[AnyRef] = {
|
def turn(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
val clockwise = args.checkBoolean(0)
|
val clockwise = args.checkBoolean(0)
|
||||||
val oldFacing = robot.facing
|
|
||||||
if (clockwise) robot.rotate(ForgeDirection.UP)
|
if (clockwise) robot.rotate(ForgeDirection.UP)
|
||||||
else robot.rotate(ForgeDirection.DOWN)
|
else robot.rotate(ForgeDirection.DOWN)
|
||||||
robot.animateTurn(oldFacing, 0.4)
|
robot.animateTurn(clockwise, Config.turnDelay)
|
||||||
context.pause(Config.turnDelay)
|
context.pause(Config.turnDelay)
|
||||||
result(true)
|
result(true)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user