mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-08-03 19:17:27 -04:00
Added a rack mountable version of the disk drive.
This commit is contained in:
parent
98e71bdc14
commit
cb7f7821c7
Binary file not shown.
BIN
assets/items.psd
BIN
assets/items.psd
Binary file not shown.
@ -1,7 +1,13 @@
|
||||
package li.cil.oc.api;
|
||||
|
||||
import com.typesafe.config.Config;
|
||||
import li.cil.oc.api.detail.*;
|
||||
import li.cil.oc.api.detail.DriverAPI;
|
||||
import li.cil.oc.api.detail.FileSystemAPI;
|
||||
import li.cil.oc.api.detail.ItemAPI;
|
||||
import li.cil.oc.api.detail.MachineAPI;
|
||||
import li.cil.oc.api.detail.ManualAPI;
|
||||
import li.cil.oc.api.detail.NanomachinesAPI;
|
||||
import li.cil.oc.api.detail.NetworkAPI;
|
||||
|
||||
/**
|
||||
* Central reference for the API.
|
||||
@ -14,6 +20,24 @@ public class API {
|
||||
public static final String ID_OWNER = "OpenComputers|Core";
|
||||
public static final String VERSION = "6.0.0-alpha";
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/**
|
||||
* The loaded config.
|
||||
*/
|
||||
public static Config config = null;
|
||||
|
||||
/**
|
||||
* Whether OpenComputers uses power.
|
||||
* <p/>
|
||||
* This is set in the init phase, so do not rely it before the post-init phase.
|
||||
*/
|
||||
public static boolean isPowerEnabled = false;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Prefer using the static methods in the respective classes in this package
|
||||
// over accessing these instances directly.
|
||||
|
||||
public static DriverAPI driver = null;
|
||||
public static FileSystemAPI fileSystem = null;
|
||||
public static ItemAPI items = null;
|
||||
@ -22,5 +46,8 @@ public class API {
|
||||
public static NanomachinesAPI nanomachines = null;
|
||||
public static NetworkAPI network = null;
|
||||
|
||||
public static Config config = null;
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
private API() {
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ item.oc.DataCard2.name=Data Card (Tier 3)
|
||||
item.oc.DebugCard.name=Debug Card
|
||||
item.oc.Debugger.name=Network Debugger
|
||||
item.oc.Disk.name=Disk Platter
|
||||
item.oc.DiskDriveMountable.name=Disk Drive
|
||||
item.oc.Drone.name=Drone
|
||||
item.oc.DroneCase0.name=Drone Case (Tier 1)
|
||||
item.oc.DroneCase1.name=Drone Case (Tier 2)
|
||||
@ -279,6 +280,7 @@ oc:tooltip.Disassembler=Separates items into their original components. §lWarni
|
||||
oc:tooltip.Disk=Primitive medium that can be used to build persistent storage devices.
|
||||
oc:tooltip.DiskDrive.CC=ComputerCraft floppies are §asupported§7.
|
||||
oc:tooltip.DiskDrive=Allows reading and writing floppies. Can be installed in robots to allow inserting floppies later on.
|
||||
oc:tooltip.DiskDriveMountable=Provides the same functionality as a normal disk drive, but must be installed in a rack.
|
||||
oc:tooltip.DiskUsage=Disk usage: %s/%s Byte
|
||||
oc:tooltip.DiskModeManaged=Mode: Managed
|
||||
oc:tooltip.DiskModeUnmanaged=Mode: Unmanaged
|
||||
|
@ -83,6 +83,11 @@ tabletCase2 {
|
||||
["oc:circuitChip2", "oc:materialCircuitBoardPrinted", ingotGold]]
|
||||
}
|
||||
|
||||
diskDriveMountable {
|
||||
input: [[obsidian, "oc:circuitChip1", obsidian]
|
||||
[fenceIron, "oc:diskDrive", fenceIron]
|
||||
[obsidian, "oc:materialCircuitBoardPrinted", obsidian]]
|
||||
}
|
||||
server1 {
|
||||
input: [[obsidian, "oc:ram4", obsidian]
|
||||
["oc:circuitChip1", "oc:circuitChip2", "oc:circuitChip1"]
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 490 B |
Binary file not shown.
After Width: | Height: | Size: 149 B |
Binary file not shown.
After Width: | Height: | Size: 481 B |
@ -88,6 +88,7 @@ object Constants {
|
||||
final val DebugCard = "debugCard"
|
||||
final val Debugger = "debugger"
|
||||
final val Disk = "disk"
|
||||
final val DiskDriveMountable = "diskDriveMountable"
|
||||
final val Drone = "drone"
|
||||
final val DroneCaseCreative = "droneCaseCreative"
|
||||
final val DroneCaseTier1 = "droneCase1"
|
||||
|
@ -21,7 +21,7 @@ object GuiHandler extends CommonGuiHandler {
|
||||
override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = {
|
||||
GuiType.Categories.get(id) match {
|
||||
case Some(GuiType.Category.Block) =>
|
||||
world.getTileEntity(x, y, z) match {
|
||||
world.getTileEntity(x, GuiType.extractY(y), z) match {
|
||||
case t: tileentity.Adapter if id == GuiType.Adapter.id =>
|
||||
new gui.Adapter(player.inventory, t)
|
||||
case t: tileentity.Assembler if id == GuiType.Assembler.id =>
|
||||
@ -46,8 +46,8 @@ object GuiHandler extends CommonGuiHandler {
|
||||
new gui.Robot(player.inventory, t.robot)
|
||||
case t: tileentity.Screen if id == GuiType.Screen.id =>
|
||||
new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled)
|
||||
case t: tileentity.Rack if GuiType.ServerInRack.exists(e => e.id == id) =>
|
||||
val slot = GuiType.ServerInRack.indexWhere(e => e.id == id)
|
||||
case t: tileentity.Rack if id == GuiType.ServerInRack.id =>
|
||||
val slot = GuiType.extractSlot(y)
|
||||
new gui.Server(player.inventory, new ServerInventory {
|
||||
override def container = t.getStackInSlot(slot)
|
||||
|
||||
|
@ -59,11 +59,12 @@ object Textures {
|
||||
val blockRaidFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/RaidFrontActivity.png")
|
||||
val blockRobot = new ResourceLocation(Settings.resourceDomain, "textures/blocks/robot.png")
|
||||
val blockScreenUpIndicator = new ResourceLocation(Settings.resourceDomain, "textures/blocks/screen/up_indicator.png")
|
||||
val blockServerFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontOn.png")
|
||||
val blockServerFrontError = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontError.png")
|
||||
val blockServerFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontActivity.png")
|
||||
val blockTerminalServerFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/TerminalServerFrontOn.png")
|
||||
val blockTerminalServerFrontPresence = new ResourceLocation(Settings.resourceDomain, "textures/blocks/TerminalServerFrontPresence.png")
|
||||
val blockRackDiskDriveActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/DiskDriveMountableActivity.png")
|
||||
val blockRackServerOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontOn.png")
|
||||
val blockRackServerError = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontError.png")
|
||||
val blockRackServerActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerFrontActivity.png")
|
||||
val blockRackTerminalServerOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/TerminalServerFrontOn.png")
|
||||
val blockRackTerminalServerPresence = new ResourceLocation(Settings.resourceDomain, "textures/blocks/TerminalServerFrontPresence.png")
|
||||
|
||||
val upgradeCrafting = new ResourceLocation(Settings.resourceDomain, "textures/model/UpgradeCrafting.png")
|
||||
val upgradeGenerator = new ResourceLocation(Settings.resourceDomain, "textures/model/UpgradeGenerator.png")
|
||||
@ -97,6 +98,7 @@ object Textures {
|
||||
|
||||
object Rack {
|
||||
val icons = Array.fill[IIcon](6)(null)
|
||||
var diskDrive: IIcon = _
|
||||
var server: IIcon = _
|
||||
var terminal: IIcon = _
|
||||
}
|
||||
@ -146,7 +148,7 @@ object Textures {
|
||||
tm.bindTexture(blockHologram)
|
||||
tm.bindTexture(blockMicrocontrollerFrontLight)
|
||||
tm.bindTexture(blockMicrocontrollerFrontOn)
|
||||
tm.bindTexture(blockServerFrontOn)
|
||||
tm.bindTexture(blockRackServerOn)
|
||||
tm.bindTexture(blockRobot)
|
||||
tm.bindTexture(blockScreenUpIndicator)
|
||||
|
||||
|
@ -36,10 +36,16 @@ object RackRenderer extends TileEntitySpecialRenderer {
|
||||
// Note: we manually sync the rack inventory for this to work.
|
||||
for (i <- 0 until rack.getSizeInventory) {
|
||||
if (rack.getStackInSlot(i) != null) {
|
||||
GL11.glPushMatrix()
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
val v0 = vOffset + i * vSize
|
||||
val v1 = vOffset + (i + 1) * vSize
|
||||
val event = new RackMountableRenderEvent.TileEntity(rack, i, rack.lastData(i), v0, v1)
|
||||
MinecraftForge.EVENT_BUS.post(event)
|
||||
|
||||
GL11.glPopAttrib()
|
||||
GL11.glPopMatrix()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ abstract class GuiHandler extends IGuiHandler {
|
||||
override def getServerGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = {
|
||||
GuiType.Categories.get(id) match {
|
||||
case Some(GuiType.Category.Block) =>
|
||||
world.getTileEntity(x, y, z) match {
|
||||
world.getTileEntity(x, GuiType.extractY(y), z) match {
|
||||
case t: tileentity.Adapter if id == GuiType.Adapter.id =>
|
||||
new container.Adapter(player.inventory, t)
|
||||
case t: tileentity.Assembler if id == GuiType.Assembler.id =>
|
||||
@ -35,8 +35,8 @@ abstract class GuiHandler extends IGuiHandler {
|
||||
new container.Robot(player.inventory, t.robot)
|
||||
case t: tileentity.Rack if id == GuiType.Rack.id =>
|
||||
new container.Rack(player.inventory, t)
|
||||
case t: tileentity.Rack if GuiType.ServerInRack.exists(e => e.id == id) =>
|
||||
val slot = GuiType.ServerInRack.indexWhere(e => e.id == id)
|
||||
case t: tileentity.Rack if id == GuiType.ServerInRack.id =>
|
||||
val slot = GuiType.extractSlot(y)
|
||||
val server = t.getMountable(slot).asInstanceOf[Server]
|
||||
new container.Server(player.inventory, server, Option(server))
|
||||
case t: tileentity.Switch if id == GuiType.Switch.id =>
|
||||
|
@ -30,12 +30,7 @@ object GuiType extends ScalaEnum {
|
||||
val Robot = new EnumVal { def name = "Robot"; def subType = GuiType.Category.Block }
|
||||
val Screen = new EnumVal { def name = "Screen"; def subType = GuiType.Category.Block }
|
||||
val Server = new EnumVal { def name = "Server"; def subType = GuiType.Category.Item }
|
||||
val ServerInRack = Array(
|
||||
new EnumVal { val slot = 0; def name = "ServerInRack"; def subType = GuiType.Category.Block },
|
||||
new EnumVal { val slot = 1; def name = "ServerInRack"; def subType = GuiType.Category.Block },
|
||||
new EnumVal { val slot = 2; def name = "ServerInRack"; def subType = GuiType.Category.Block },
|
||||
new EnumVal { val slot = 3; def name = "ServerInRack"; def subType = GuiType.Category.Block }
|
||||
)
|
||||
val ServerInRack = new EnumVal { def name = "ServerInRack"; def subType = GuiType.Category.Block }
|
||||
val Switch = new EnumVal { def name = "Switch"; def subType = GuiType.Category.Block }
|
||||
val Tablet = new EnumVal { def name = "Tablet"; def subType = GuiType.Category.Item }
|
||||
val TabletInner = new EnumVal { def name = "TabletInner"; def subType = GuiType.Category.Item }
|
||||
@ -50,4 +45,10 @@ object GuiType extends ScalaEnum {
|
||||
val Entity = new EnumVal { def name = "Entity" }
|
||||
val Item = new EnumVal { def name = "Item" }
|
||||
}
|
||||
|
||||
def embedSlot(y: Int, slot: Int) = (y & 0x00FFFFFF) | (slot << 6)
|
||||
|
||||
def extractY(value: Int) = value & 0x00FFFFFF
|
||||
|
||||
def extractSlot(value: Int) = (value >>> 6) & 0xFF
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ class Rack extends RedstoneAware with traits.SpecialBlock with traits.PowerAccep
|
||||
override def registerBlockIcons(iconRegister: IIconRegister) = {
|
||||
super.registerBlockIcons(iconRegister)
|
||||
System.arraycopy(icons, 0, Textures.Rack.icons, 0, icons.length)
|
||||
Textures.Rack.diskDrive = iconRegister.registerIcon(Settings.resourceDomain + ":" + "DiskDriveMountable")
|
||||
Textures.Rack.server = iconRegister.registerIcon(Settings.resourceDomain + ":" + "ServerFront")
|
||||
Textures.Rack.terminal = iconRegister.registerIcon(Settings.resourceDomain + ":" + "TerminalServerFront")
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
package li.cil.oc.common.component
|
||||
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.internal.Keyboard.UsabilityChecker
|
||||
import li.cil.oc.api.network.Component
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.nbt.NBTTagString
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
//class Terminal(val rack: tileentity.Rack, val number: Int) {
|
||||
// val buffer = {
|
||||
// val screenItem = api.Items.get(Constants.BlockName.ScreenTier1).createItemStack(1)
|
||||
// val buffer = api.Driver.driverFor(screenItem, rack.getClass).createEnvironment(screenItem, rack).asInstanceOf[api.component.TextBuffer]
|
||||
// val (maxWidth, maxHeight) = Settings.screenResolutionsByTier(Tier.Three)
|
||||
// buffer.setMaximumResolution(maxWidth, maxHeight)
|
||||
// buffer.setMaximumColorDepth(Settings.screenDepthsByTier(Tier.Three))
|
||||
// buffer
|
||||
// }
|
||||
//
|
||||
// val keyboard = {
|
||||
// val keyboardItem = api.Items.get(Constants.BlockName.Keyboard).createItemStack(1)
|
||||
// val keyboard = api.Driver.driverFor(keyboardItem, rack.getClass).createEnvironment(keyboardItem, rack).asInstanceOf[api.component.Keyboard]
|
||||
// keyboard.setUsableOverride(new UsabilityChecker {
|
||||
// override def isUsableByPlayer(keyboard: api.component.Keyboard, player: EntityPlayer) = {
|
||||
// val stack = player.getHeldItem
|
||||
// Delegator.subItem(stack) match {
|
||||
// case Some(t: item.Terminal) if stack.hasTagCompound => keys.contains(stack.getTagCompound.getString(Settings.namespace + "key"))
|
||||
// case _ => false
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// keyboard
|
||||
// }
|
||||
//
|
||||
// if (buffer.node != null) {
|
||||
// buffer.node.asInstanceOf[Component].setVisibility(Visibility.Neighbors)
|
||||
// keyboard.node.asInstanceOf[Component].setVisibility(Visibility.Neighbors)
|
||||
// }
|
||||
//
|
||||
// val keys = mutable.ListBuffer.empty[String]
|
||||
//
|
||||
// def connect(node: Node) {
|
||||
// if (keys.size > 0) {
|
||||
// node.connect(buffer.node)
|
||||
// node.connect(keyboard.node)
|
||||
// buffer.node.connect(keyboard.node)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // ----------------------------------------------------------------------- //
|
||||
//
|
||||
// def load(nbt: NBTTagCompound) {
|
||||
// buffer.load(nbt.getCompoundTag(Settings.namespace + "buffer"))
|
||||
// keyboard.load(nbt.getCompoundTag(Settings.namespace + "keyboard"))
|
||||
// // Compatibility for previous dev versions where there was only one term.
|
||||
// if (nbt.hasKey(Settings.namespace + "key")) {
|
||||
// keys += nbt.getString(Settings.namespace + "key")
|
||||
// }
|
||||
// nbt.getTagList(Settings.namespace + "keys", NBT.TAG_STRING).foreach((tag: NBTTagString) => keys += tag.func_150285_a_())
|
||||
// }
|
||||
//
|
||||
// def save(nbt: NBTTagCompound) {
|
||||
// nbt.setNewCompoundTag(Settings.namespace + "buffer", buffer.save)
|
||||
// nbt.setNewCompoundTag(Settings.namespace + "keyboard", keyboard.save)
|
||||
// nbt.setNewTagList(Settings.namespace + "keys", keys)
|
||||
// }
|
||||
//
|
||||
// @SideOnly(Side.CLIENT)
|
||||
// def readFromNBTForClient(nbt: NBTTagCompound) {
|
||||
// buffer.load(nbt)
|
||||
// nbt.getTagList("keys", NBT.TAG_STRING).foreach((tag: NBTTagString) => keys += tag.func_150285_a_())
|
||||
// }
|
||||
//
|
||||
// def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
// buffer.save(nbt)
|
||||
// nbt.setNewTagList("keys", keys)
|
||||
// }
|
||||
//}
|
@ -7,6 +7,7 @@ import li.cil.oc.api.internal.Rack
|
||||
import li.cil.oc.common.tileentity.Case
|
||||
import li.cil.oc.common.tileentity.DiskDrive
|
||||
import li.cil.oc.common.tileentity.Raid
|
||||
import li.cil.oc.server.component.DiskDriveMountable
|
||||
import li.cil.oc.server.component.Server
|
||||
|
||||
object FileSystemAccessHandler {
|
||||
@ -22,6 +23,12 @@ object FileSystemAccessHandler {
|
||||
server.lastAccess = System.currentTimeMillis()
|
||||
t.markChanged(slot)
|
||||
}
|
||||
case diskDrive: DiskDriveMountable =>
|
||||
val containsNode = diskDrive.filesystemNode.contains(e.getNode)
|
||||
if (containsNode) {
|
||||
diskDrive.lastAccess = System.currentTimeMillis()
|
||||
t.markChanged(slot)
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,20 @@ import li.cil.oc.api
|
||||
import li.cil.oc.api.event.RackMountableRenderEvent
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.client.renderer.tileentity.RenderUtil
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.renderer.OpenGlHelper
|
||||
import net.minecraft.client.renderer.entity.RenderItem
|
||||
import net.minecraft.client.renderer.entity.RenderManager
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object RackMountableRenderHandler {
|
||||
lazy val DiskDriveMountable = api.Items.get(Constants.ItemName.DiskDriveMountable)
|
||||
|
||||
lazy val Servers = Array(
|
||||
api.Items.get(Constants.ItemName.ServerTier1),
|
||||
api.Items.get(Constants.ItemName.ServerTier2),
|
||||
@ -21,19 +31,52 @@ object RackMountableRenderHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
def onRackMountableRendering(e: RackMountableRenderEvent.TileEntity): Unit = {
|
||||
if (e.data != null && Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) {
|
||||
if (e.data != null && DiskDriveMountable == api.Items.get(e.rack.getStackInSlot(e.mountable))) {
|
||||
// Disk drive.
|
||||
|
||||
if (e.data.hasKey("disk")) {
|
||||
val stack = ItemStack.loadItemStackFromNBT(e.data.getCompoundTag("disk"))
|
||||
if (stack != null) {
|
||||
GL11.glPushMatrix()
|
||||
GL11.glScalef(1, -1, 1)
|
||||
GL11.glTranslatef(10 / 16f, -(3.5f + e.mountable * 3f) / 16f, 1 / 16f)
|
||||
GL11.glRotatef(90, -1, 0, 0)
|
||||
|
||||
val brightness = e.rack.world.getLightBrightnessForSkyBlocks(BlockPosition(e.rack).offset(e.rack.facing), 0)
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536)
|
||||
|
||||
// This is very 'meh', but item frames do it like this, too!
|
||||
val entity = new EntityItem(e.rack.world, 0, 0, 0, stack)
|
||||
entity.hoverStart = 0
|
||||
RenderItem.renderInFrame = true
|
||||
RenderManager.instance.renderEntityWithPosYaw(entity, 0, 0, 0, 0, 0)
|
||||
RenderItem.renderInFrame = false
|
||||
GL11.glPopMatrix()
|
||||
}
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - e.data.getLong("lastAccess") < 400 && e.rack.world.rand.nextDouble() > 0.1) {
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
e.renderOverlay(Textures.blockRackDiskDriveActivity)
|
||||
|
||||
RenderState.enableLighting()
|
||||
}
|
||||
}
|
||||
else if (e.data != null && Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) {
|
||||
// Server.
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
if (e.data.getBoolean("isRunning")) {
|
||||
e.renderOverlay(Textures.blockServerFrontOn)
|
||||
e.renderOverlay(Textures.blockRackServerOn)
|
||||
}
|
||||
if (e.data.getBoolean("hasErrored") && RenderUtil.shouldShowErrorLight(e.rack.hashCode * (e.mountable + 1))) {
|
||||
e.renderOverlay(Textures.blockServerFrontError)
|
||||
e.renderOverlay(Textures.blockRackServerError)
|
||||
}
|
||||
if (System.currentTimeMillis() - e.data.getLong("lastAccess") < 400 && e.rack.world.rand.nextDouble() > 0.1) {
|
||||
e.renderOverlay(Textures.blockServerFrontActivity)
|
||||
e.renderOverlay(Textures.blockRackServerActivity)
|
||||
}
|
||||
|
||||
RenderState.enableLighting()
|
||||
@ -43,13 +86,13 @@ object RackMountableRenderHandler {
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
e.renderOverlay(Textures.blockTerminalServerFrontOn)
|
||||
e.renderOverlay(Textures.blockRackTerminalServerOn)
|
||||
val countConnected = e.data.getTagList("keys", NBT.TAG_STRING).tagCount()
|
||||
|
||||
if (countConnected > 0) {
|
||||
val u0 = 7 / 16f
|
||||
val u1 = u0 + (2 * countConnected - 1) / 16f
|
||||
e.renderOverlay(Textures.blockTerminalServerFrontPresence, u0, u1)
|
||||
e.renderOverlay(Textures.blockRackTerminalServerPresence, u0, u1)
|
||||
}
|
||||
|
||||
RenderState.enableLighting()
|
||||
@ -58,7 +101,11 @@ object RackMountableRenderHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
def onRackMountableRendering(e: RackMountableRenderEvent.Block): Unit = {
|
||||
if (Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) {
|
||||
if (DiskDriveMountable == api.Items.get(e.rack.getStackInSlot(e.mountable))) {
|
||||
// Disk drive.
|
||||
e.setFrontTextureOverride(Textures.Rack.diskDrive)
|
||||
}
|
||||
else if (Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) {
|
||||
// Server.
|
||||
e.setFrontTextureOverride(Textures.Rack.server)
|
||||
}
|
||||
|
@ -531,6 +531,7 @@ object Items extends ItemAPI {
|
||||
|
||||
// 1.6.0
|
||||
Recipes.addSubItem(new item.TerminalServer(multi), Constants.ItemName.TerminalServer, "oc:terminalServer")
|
||||
Recipes.addSubItem(new item.DiskDriveMountable(multi), Constants.ItemName.DiskDriveMountable, "oc:diskDriveMountable")
|
||||
|
||||
// Register aliases.
|
||||
for ((k, v) <- aliases) {
|
||||
|
@ -13,7 +13,6 @@ import li.cil.oc.api.driver.item.Chargeable
|
||||
import li.cil.oc.api.event.RobotRenderEvent.MountPoint
|
||||
import li.cil.oc.api.internal.Robot
|
||||
import li.cil.oc.client.renderer.item.UpgradeRenderer
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import net.minecraft.client.renderer.texture.IIconRegister
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
@ -123,14 +122,13 @@ class Delegator extends Item with driver.item.UpgradeRenderer with Chargeable {
|
||||
|
||||
override def getChestGenBase(chest: ChestGenHooks, rnd: Random, original: WeightedRandomChestContent) = original
|
||||
|
||||
override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer) = {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case drive: tileentity.DiskDrive => true
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer) =
|
||||
Delegator.subItem(player.getHeldItem) match {
|
||||
case Some(subItem) => subItem.doesSneakBypassUse(BlockPosition(x, y, z, world), player)
|
||||
case _ => super.doesSneakBypassUse(world, x, y, z, player)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean =
|
||||
Delegator.subItem(stack) match {
|
||||
|
@ -0,0 +1,3 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class DiskDriveMountable(val parent: Delegator) extends traits.Delegate
|
@ -3,7 +3,9 @@ package li.cil.oc.common.item
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.Color
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class FloppyDisk(val parent: Delegator) extends traits.Delegate with traits.FileSystemLike {
|
||||
@ -28,4 +30,6 @@ class FloppyDisk(val parent: Delegator) extends traits.Delegate with traits.File
|
||||
icons(index) = iconRegister.registerIcon(baseTextureName + color)
|
||||
}
|
||||
}
|
||||
|
||||
override def doesSneakBypassUse(position: BlockPosition, player: EntityPlayer): Boolean = true
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ trait Delegate {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def doesSneakBypassUse(position: BlockPosition, player: EntityPlayer) = false
|
||||
|
||||
def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = false
|
||||
|
||||
def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = false
|
||||
|
@ -21,10 +21,6 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class DiskDrive extends traits.Environment with traits.ComponentInventory with traits.Rotatable with Analyzable {
|
||||
val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("disk_drive").
|
||||
create()
|
||||
|
||||
// Used on client side to check whether to render disk activity indicators.
|
||||
var lastAccess = 0L
|
||||
|
||||
@ -34,6 +30,11 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Environment
|
||||
|
||||
val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("disk_drive").
|
||||
create()
|
||||
|
||||
@Callback(doc = """function():boolean -- Checks whether some medium is currently in the drive.""")
|
||||
def isEmpty(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
@ -58,12 +59,12 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Analyzable
|
||||
|
||||
override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = filesystemNode.fold(null: Array[Node])(Array(_))
|
||||
|
||||
override def canUpdate = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// IInventory
|
||||
|
||||
override def getSizeInventory = 1
|
||||
|
||||
@ -72,6 +73,9 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
|
||||
case _ => false
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// ComponentInventory
|
||||
|
||||
override protected def onItemAdded(slot: Int, stack: ItemStack) {
|
||||
super.onItemAdded(slot, stack)
|
||||
components(slot) match {
|
||||
@ -95,20 +99,23 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// TileEntity
|
||||
|
||||
override def canUpdate = false
|
||||
|
||||
@SideOnly(Side.CLIENT) override
|
||||
def readFromNBTForClient(nbt: NBTTagCompound) {
|
||||
super.readFromNBTForClient(nbt)
|
||||
items(0) match {
|
||||
case Some(stack) => nbt.setNewCompoundTag("disk", stack.writeToNBT)
|
||||
case _ =>
|
||||
if (nbt.hasKey("disk")) {
|
||||
setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("disk")))
|
||||
}
|
||||
}
|
||||
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForClient(nbt)
|
||||
if (nbt.hasKey("disk")) {
|
||||
setInventorySlotContents(0, ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("disk")))
|
||||
items(0) match {
|
||||
case Some(stack) => nbt.setNewCompoundTag("disk", stack.writeToNBT)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo
|
||||
// Cache changes to inventory slots on the client side to avoid recreating
|
||||
// components when we don't have to and the slots are just cleared by MC
|
||||
// temporarily.
|
||||
private val pendingRemovalsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private val pendingAddsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private lazy val pendingRemovalsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private lazy val pendingAddsActual = mutable.ArrayBuffer.fill(getSizeInventory)(None: Option[ItemStack])
|
||||
private var updateScheduled = false
|
||||
def pendingRemovals = {
|
||||
adjustSize(pendingRemovalsActual)
|
||||
|
@ -0,0 +1,32 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.api.network.EnvironmentHost
|
||||
import li.cil.oc.api.network.ManagedEnvironment
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.util.ExtendedInventory._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
object DriverDiskDriveMountable extends Item with HostAware {
|
||||
override def worksWith(stack: ItemStack): Boolean = isOneOf(stack,
|
||||
api.Items.get(Constants.ItemName.DiskDriveMountable))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = host match {
|
||||
case rack: tileentity.Rack => new component.DiskDriveMountable(rack, rack.indexOf(stack))
|
||||
case _ => null // Welp.
|
||||
}
|
||||
|
||||
override def slot(stack: ItemStack): String = Slot.RackMountable
|
||||
|
||||
override def dataTag(stack: ItemStack): NBTTagCompound = {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
stack.getTagCompound
|
||||
}
|
||||
}
|
@ -125,6 +125,7 @@ object ModOpenComputers extends ModProxy {
|
||||
api.Driver.add(DriverScreen)
|
||||
api.Driver.add(DriverTransposer)
|
||||
|
||||
api.Driver.add(DriverDiskDriveMountable)
|
||||
api.Driver.add(DriverServer)
|
||||
api.Driver.add(DriverTerminalServer)
|
||||
|
||||
|
@ -100,10 +100,10 @@ object PacketSender {
|
||||
}
|
||||
|
||||
// Avoid spamming the network with disk activity notices.
|
||||
val fileSystemAccessTimeouts = mutable.WeakHashMap.empty[EnvironmentHost, mutable.Map[String, Long]]
|
||||
val fileSystemAccessTimeouts = mutable.WeakHashMap.empty[Node, mutable.Map[String, Long]]
|
||||
|
||||
def sendFileSystemActivity(node: Node, host: EnvironmentHost, name: String) = fileSystemAccessTimeouts.synchronized {
|
||||
fileSystemAccessTimeouts.get(host) match {
|
||||
fileSystemAccessTimeouts.get(node) match {
|
||||
case Some(hostTimeouts) if hostTimeouts.getOrElse(name, 0L) > System.currentTimeMillis() => // Cooldown.
|
||||
case _ =>
|
||||
val event = host match {
|
||||
@ -112,7 +112,7 @@ object PacketSender {
|
||||
}
|
||||
MinecraftForge.EVENT_BUS.post(event)
|
||||
if (!event.isCanceled) {
|
||||
fileSystemAccessTimeouts.getOrElseUpdate(host, mutable.Map.empty) += name -> (System.currentTimeMillis() + 500)
|
||||
fileSystemAccessTimeouts.getOrElseUpdate(node, mutable.Map.empty) += name -> (System.currentTimeMillis() + 500)
|
||||
|
||||
val pb = new SimplePacketBuilder(PacketType.FileSystemActivity)
|
||||
|
||||
|
@ -0,0 +1,172 @@
|
||||
package li.cil.oc.server.component
|
||||
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.api.component.RackBusConnectable
|
||||
import li.cil.oc.api.component.RackMountable
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network.Analyzable
|
||||
import li.cil.oc.api.network.Component
|
||||
import li.cil.oc.api.network.EnvironmentHost
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Sound
|
||||
import li.cil.oc.common.inventory.ComponentInventory
|
||||
import li.cil.oc.common.inventory.ItemStackInventory
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class DiskDriveMountable(val rack: tileentity.Rack, val slot: Int) extends prefab.ManagedEnvironment with ItemStackInventory with ComponentInventory with RackMountable with Analyzable {
|
||||
// Stored for filling data packet when queried.
|
||||
var lastAccess = 0L
|
||||
|
||||
def filesystemNode = components(0) match {
|
||||
case Some(environment) => Option(environment.node)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Environment
|
||||
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("disk_drive").
|
||||
create()
|
||||
|
||||
@Callback(doc = """function():boolean -- Checks whether some medium is currently in the drive.""")
|
||||
def isEmpty(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
result(filesystemNode.isEmpty)
|
||||
}
|
||||
|
||||
@Callback(doc = """function([velocity:number]):boolean -- Eject the currently present medium from the drive.""")
|
||||
def eject(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val velocity = args.optDouble(0, 0) max 0 min 1
|
||||
val ejected = decrStackSize(0, 1)
|
||||
if (ejected != null && ejected.stackSize > 0) {
|
||||
val entity = InventoryUtils.spawnStackInWorld(rack.position, ejected, Option(rack.facing))
|
||||
if (entity != null) {
|
||||
val vx = rack.facing.offsetX * velocity
|
||||
val vy = rack.facing.offsetY * velocity
|
||||
val vz = rack.facing.offsetZ * velocity
|
||||
entity.addVelocity(vx, vy, vz)
|
||||
}
|
||||
result(true)
|
||||
}
|
||||
else result(false)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Analyzable
|
||||
|
||||
override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = filesystemNode.fold(null: Array[Node])(Array(_))
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// ItemStackInventory
|
||||
|
||||
override def host: EnvironmentHost = rack
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// IInventory
|
||||
|
||||
override def getSizeInventory: Int = 1
|
||||
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack))) match {
|
||||
case (0, Some(driver)) => driver.slot(stack) == Slot.Floppy
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def isUseableByPlayer(player: EntityPlayer): Boolean = rack.isUseableByPlayer(player)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// ComponentInventory
|
||||
|
||||
override def container: ItemStack = rack.getStackInSlot(slot)
|
||||
|
||||
override protected def onItemAdded(slot: Int, stack: ItemStack) {
|
||||
super.onItemAdded(slot, stack)
|
||||
components(slot) match {
|
||||
case Some(environment) => environment.node match {
|
||||
case component: Component => component.setVisibility(Visibility.Network)
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
Sound.playDiskInsert(rack)
|
||||
if (rack.isServer) {
|
||||
rack.markChanged(this.slot)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def onItemRemoved(slot: Int, stack: ItemStack) {
|
||||
super.onItemRemoved(slot, stack)
|
||||
Sound.playDiskEject(rack)
|
||||
if (rack.isServer) {
|
||||
rack.markChanged(this.slot)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// ManagedEnvironment
|
||||
|
||||
override def canUpdate: Boolean = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Persistable
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
super[ManagedEnvironment].load(nbt)
|
||||
super[ComponentInventory].load(nbt)
|
||||
connectComponents()
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
super[ManagedEnvironment].save(nbt)
|
||||
super[ComponentInventory].save(nbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// RackMountable
|
||||
|
||||
override def getData: NBTTagCompound = {
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setLong("lastAccess", lastAccess)
|
||||
nbt.setTag("disk", toNbt(getStackInSlot(0)))
|
||||
nbt
|
||||
}
|
||||
|
||||
override def getConnectableCount: Int = 0
|
||||
|
||||
override def getConnectableAt(index: Int): RackBusConnectable = null
|
||||
|
||||
override def onActivate(player: EntityPlayer, side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||
if (player.isSneaking) {
|
||||
val isDiskInDrive = getStackInSlot(0) != null
|
||||
val isHoldingDisk = isItemValidForSlot(0, player.getHeldItem)
|
||||
if (isDiskInDrive) {
|
||||
if (rack.isServer) {
|
||||
InventoryUtils.dropSlot(rack.position, this, 0, 1, Option(rack.facing))
|
||||
}
|
||||
}
|
||||
if (isHoldingDisk) {
|
||||
// Insert the disk.
|
||||
setInventorySlotContents(0, player.inventory.decrStackSize(player.inventory.currentItem, 1))
|
||||
}
|
||||
isDiskInDrive || isHoldingDisk
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// StateAware
|
||||
|
||||
override def getCurrentState: util.EnumSet[api.util.StateAware.State] = util.EnumSet.noneOf(classOf[api.util.StateAware.State])
|
||||
}
|
@ -163,7 +163,7 @@ class Server(val rack: tileentity.Rack, val slot: Int) extends Environment with
|
||||
}
|
||||
}
|
||||
else {
|
||||
player.openGui(OpenComputers, GuiType.ServerInRack(slot).id, world, rack.x, rack.y, rack.z)
|
||||
player.openGui(OpenComputers, GuiType.ServerInRack.id, world, rack.x, GuiType.embedSlot(rack.y, slot), rack.z)
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -28,6 +28,8 @@ object ExtendedWorld {
|
||||
def getTileEntity(host: EnvironmentHost): TileEntity = getTileEntity(BlockPosition(host))
|
||||
|
||||
def isAirBlock(position: BlockPosition) = world.isAirBlock(position.x, position.y, position.z)
|
||||
|
||||
def getLightBrightnessForSkyBlocks(position: BlockPosition, minBrightness: Int) = world.getLightBrightnessForSkyBlocks(position.x, position.y, position.z, minBrightness)
|
||||
}
|
||||
|
||||
class ExtendedWorld(override val world: World) extends ExtendedBlockAccess(world) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user