mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 02:12:42 -04:00
Added microcontrollers, closes #711.
Solar generator is now tier two to allow better balance of microcontroller.
This commit is contained in:
parent
981d2ffb6f
commit
451ab1b4d4
Binary file not shown.
BIN
assets/items.psd
BIN
assets/items.psd
Binary file not shown.
25
src/main/java/li/cil/oc/api/internal/Microcontroller.java
Normal file
25
src/main/java/li/cil/oc/api/internal/Microcontroller.java
Normal file
@ -0,0 +1,25 @@
|
||||
package li.cil.oc.api.internal;
|
||||
|
||||
import li.cil.oc.api.driver.EnvironmentHost;
|
||||
import li.cil.oc.api.machine.Machine;
|
||||
import li.cil.oc.api.network.Environment;
|
||||
|
||||
/**
|
||||
* This interface is implemented as a marker by microcontrollers.
|
||||
* <p/>
|
||||
* This is implemented by microcontroller tile entities. That means you can
|
||||
* use this to check for microcontrollers by using:
|
||||
* <pre>
|
||||
* if (tileEntity instanceof Microcontroller) {
|
||||
* </pre>
|
||||
* <p/>
|
||||
* The only purpose is to allow identifying tile entities as microcontrollers
|
||||
* via the API, i.e. without having to link against internal classes. This
|
||||
* also means that <em>you should not implement this</em>.
|
||||
*/
|
||||
public interface Microcontroller extends Environment, EnvironmentHost, Rotatable {
|
||||
/**
|
||||
* The machine currently hosted by this computer case.
|
||||
*/
|
||||
Machine machine();
|
||||
}
|
@ -667,6 +667,20 @@ opencomputers {
|
||||
|
||||
# The amount of energy pushing blocks with the piston upgrade costs.
|
||||
pistonPush: 20
|
||||
|
||||
# Energy it costs to re-program an EEPROM. This is deliberately
|
||||
# expensive, to discourage frequent re-writing of EEPROMs.
|
||||
eepromWrite: 50
|
||||
|
||||
# Amount of energy a microcontroller consumes per tick while running.
|
||||
microcontroller: 0.1
|
||||
|
||||
# The base energy cost for assembling a microcontroller.
|
||||
microcontrollerAssemblyBase: 10000
|
||||
|
||||
# The additional amount of energy required to assemble a
|
||||
# microcontroller for each point of complexity.
|
||||
microcontrollerAssemblyComplexity: 10000
|
||||
}
|
||||
|
||||
# The rate at which different blocks accept external power. All of these
|
||||
|
@ -19,6 +19,7 @@ tile.oc.geolyzer.name=Geolyzer
|
||||
tile.oc.keyboard.name=Keyboard
|
||||
tile.oc.hologram1.name=Hologram Projector (Tier 1)
|
||||
tile.oc.hologram2.name=Hologram Projector (Tier 2)
|
||||
tile.oc.microcontroller.name=Microcontroller
|
||||
tile.oc.motionSensor.name=Motion Sensor
|
||||
tile.oc.powerConverter.name=Power Converter
|
||||
tile.oc.powerDistributor.name=Power Distributor
|
||||
@ -74,6 +75,7 @@ item.oc.Memory5.name=Memory (Tier 3.5)
|
||||
item.oc.Microchip0.name=Microchip (Tier 1)
|
||||
item.oc.Microchip1.name=Microchip (Tier 2)
|
||||
item.oc.Microchip2.name=Microchip (Tier 3)
|
||||
item.oc.MicrocontrollerCase.name=Microcontroller Case
|
||||
item.oc.NetworkCard.name=Network Card
|
||||
item.oc.NumPad.name=Numeric Keypad
|
||||
item.oc.PrintedCircuitBoard.name=Printed Circuit Board (PCB)
|
||||
@ -230,6 +232,8 @@ oc:tooltip.MaterialCosts=Hold [§f%s§7] for material costs.
|
||||
oc:tooltip.Materials=Materials:
|
||||
oc:tooltip.Memory=Required to get computers to run. The more you have, the more complex the programs you can run.
|
||||
oc:tooltip.Microchip=The chip formerly known as Integrated Circuit. I have no idea why this works with redstone, but it does.
|
||||
oc:tooltip.Microcontroller=Microcontrollers are computers boiled down to the essentials. They are intended to take care of very specific tasks, running only a single program that is provided on the EEPROM built into them.
|
||||
oc:tooltip.MicrocontrollerCase=Base component for building microcontrollers. Place it into an assembler to add further components and assemble a microcontroller.
|
||||
oc:tooltip.MotionSensor=Can detect movement of nearby living beings. Requires clear line-of-sight.
|
||||
oc:tooltip.NetworkCard=Allows distant computers connected by other blocks (such as cable) to communicate by sending messages to each other.
|
||||
oc:tooltip.PowerAcceptor=Energy conversion speed: §f%s/t§7
|
||||
@ -299,6 +303,7 @@ item.oc.HardDiskDrive.usage=The §oHard Disk Drives§r are the higher tier stora
|
||||
item.oc.InternetCard.usage=The §oInternet Card§r grants computers access to the internet. It provides ways to perform simple HTTP requests, as well as to open plain TCP client sockets that can be read and written to.[nl][nl]Installing an internet card in a computer will also attach a custom file system that contains a few internet related applications, such as one for downloading and uploading snippets from and to pastebin as well as a wannabe wget clone that allows downloading data from arbitrary HTTP URLs.
|
||||
item.oc.LinkedCard.usage=The §oLinked Card§r is a specialized but advanced version of a network card. It can only operate in pairs, providing a point-to-point communication between the paired cards. In return the distance the cards can communicate over is unlimited. They can even communicate when in different dimensions.
|
||||
item.oc.Memory.usage=§oMemory§r is, like a §oCPU§r, an essential part in all computers. Depending on the CPU's architecture, the memory has a very essential effect on what a computer can and cannot do. For the standard Lua architecture, for example, it controls the actual amount of memory Lua scripts can use. This means that to run larger and more memory-intensive programs, you'll need more RAM.
|
||||
item.oc.MicrocontrollerCase.usage=The §oMicrocontroller Case§r is the base part when building microcontrollers in the §oAssembler§r. Microcontrollers are very primitive computers. They may only contain a very limited number of components, and are intended to be used in very specific use-cases, such as transforming or reacting to redstone signals, or processing network messages.[nl][nl]They do not have an actual file system. All programming must be done using the EEPROM chip built into them. This chip can be swapped for another one by crafting a microcontroller with the chip to insert. The old EEPROM will be returned to your inventory.[nl][nl]While they also require power to run, they consume very little energy.
|
||||
item.oc.NetworkCard.usage=The §oNetwork Card§r allows computers to send and receive network messages. Such messages (or packets) can be either sent as a broadcast, in which case they will be sent to all nodes in the same subnetwork, or sent to specific target, in which case they will only be received by the node with the specified target address. §oSwitches§r and §oAccess Points§r can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more switches.
|
||||
item.oc.RedstoneCard.usage=The §oRedstone Card§r allows computers to read and emit analog redstone signal in adjacent blocks. When an ingoing signal strength changes, a signal is injected into the computer.[nl][nl]If there are any supported mods present that provide bundled redstone facilities, such as RedLogic, Project Red or MineFactory Reloaded, or mods that provide wireless redstone facilities such as WR-CBE and Slimevoid's Wireless mod, a second tier card is available that allows interacting with these systems.[nl][nl]The side provided to the several methods are relative to the orientation of the computer case / robot / server rack. That means when looking at the front of the computer, right is at your left and vice versa.
|
||||
item.oc.Server.usage=§oServers§r are a form of higher tier computer. They can be configured by holding them in the hand and rightclicking - like opening a backpack or ender pouch, for example. After inserting CPU, memory and cards, the server has to be placed inside a §oServer Rack§r. For more information see the server rack entry.
|
||||
|
@ -6,6 +6,11 @@ analyzer {
|
||||
["oc:materialTransistor", nuggetGold, ""]
|
||||
["oc:materialCircuitBoardPrinted", nuggetGold, ""]]
|
||||
}
|
||||
microcontrollerCase {
|
||||
input: [[nuggetIron, "oc:circuitChip1", nuggetIron]
|
||||
[redstone, chest, redstone]
|
||||
[nuggetIron, "oc:materialCircuitBoardPrinted", nuggetIron]]
|
||||
}
|
||||
terminal {
|
||||
input: [[nuggetIron, "oc:solarGeneratorUpgrade", nuggetIron]
|
||||
["oc:circuitChip3", "oc:screen2", "oc:wlanCard"]
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 617 B |
Binary file not shown.
After Width: | Height: | Size: 153 B |
Binary file not shown.
After Width: | Height: | Size: 150 B |
Binary file not shown.
After Width: | Height: | Size: 614 B |
Binary file not shown.
After Width: | Height: | Size: 500 B |
Binary file not shown.
After Width: | Height: | Size: 596 B |
@ -178,6 +178,10 @@ class Settings(val config: Config) {
|
||||
val disassemblerItemCost = config.getDouble("power.cost.disassemblerPerItem") max 0
|
||||
val chunkloaderCost = config.getDouble("power.cost.chunkloaderCost") max 0
|
||||
val pistonCost = config.getDouble("power.cost.pistonPush") max 0
|
||||
val microcontrollerCost = config.getDouble("power.cost.microcontroller") max 0
|
||||
val eepromWriteCost = config.getDouble("power.cost.eepromWrite") max 0
|
||||
val microcontrollerBaseCost = config.getDouble("power.cost.microcontrollerAssemblyBase") max 0
|
||||
val microcontrollerComplexityCost = config.getDouble("power.cost.microcontrollerAssemblyComplexity") max 0
|
||||
|
||||
// power.rate
|
||||
val accessPointRate = config.getDouble("power.rate.accessPoint") max 0
|
||||
|
@ -55,6 +55,7 @@ private[oc] class Proxy extends CommonProxy {
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.DiskDrive], DiskDriveRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Geolyzer], GeolyzerRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Hologram], HologramRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Microcontroller], MicrocontrollerRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.PowerDistributor], PowerDistributorRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Raid], RaidRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.ServerRack], ServerRackRenderer)
|
||||
|
@ -37,6 +37,8 @@ object Textures {
|
||||
val blockCaseFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/CaseFrontActivity.png")
|
||||
val blockDiskDriveFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/DiskDriveFrontActivity.png")
|
||||
val blockHologram = new ResourceLocation(Settings.resourceDomain, "textures/blocks/HologramEffect.png")
|
||||
val blockMicrocontrollerFrontLight = new ResourceLocation(Settings.resourceDomain, "textures/blocks/MicrocontrollerFrontLight.png")
|
||||
val blockMicrocontrollerFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/MicrocontrollerFrontOn.png")
|
||||
val blockRackFrontOn = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerRackFrontOn.png")
|
||||
val blockRackFrontActivity = new ResourceLocation(Settings.resourceDomain, "textures/blocks/ServerRackFrontActivity.png")
|
||||
val blockRaidFrontError = new ResourceLocation(Settings.resourceDomain, "textures/blocks/RaidFrontError.png")
|
||||
@ -105,7 +107,10 @@ object Textures {
|
||||
tm.bindTexture(guiSlot)
|
||||
|
||||
tm.bindTexture(blockCaseFrontOn)
|
||||
tm.bindTexture(blockCaseFrontActivity)
|
||||
tm.bindTexture(blockHologram)
|
||||
tm.bindTexture(blockMicrocontrollerFrontLight)
|
||||
tm.bindTexture(blockMicrocontrollerFrontOn)
|
||||
tm.bindTexture(blockRackFrontOn)
|
||||
tm.bindTexture(blockRobot)
|
||||
tm.bindTexture(blockScreenUpIndicator)
|
||||
|
@ -0,0 +1,62 @@
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.tileentity.Microcontroller
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object MicrocontrollerRenderer extends TileEntitySpecialRenderer {
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float) {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val mcu = tileEntity.asInstanceOf[Microcontroller]
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
RenderState.disableLighting()
|
||||
RenderState.makeItBlend()
|
||||
RenderState.setBlendAlpha(1)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
|
||||
mcu.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.505)
|
||||
GL11.glScalef(1, -1, 1)
|
||||
|
||||
bindTexture(Textures.blockMicrocontrollerFrontLight)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, 1, 0, 0, 1)
|
||||
t.addVertexWithUV(1, 1, 0, 1, 1)
|
||||
t.addVertexWithUV(1, 0, 0, 1, 0)
|
||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||
t.draw()
|
||||
|
||||
if (mcu.isRunning) {
|
||||
bindTexture(Textures.blockMicrocontrollerFrontOn)
|
||||
val t = Tessellator.instance
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(0, 1, 0, 0, 1)
|
||||
t.addVertexWithUV(1, 1, 0, 1, 1)
|
||||
t.addVertexWithUV(1, 0, 0, 1, 0)
|
||||
t.addVertexWithUV(0, 0, 0, 0, 0)
|
||||
t.draw()
|
||||
}
|
||||
|
||||
GL11.glPopMatrix()
|
||||
GL11.glPopAttrib()
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
|
||||
import cpw.mods.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent
|
||||
import li.cil.oc._
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.detail.ItemInfo
|
||||
import li.cil.oc.client.renderer.PetRenderer
|
||||
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.common.tileentity.traits.power
|
||||
@ -20,6 +21,7 @@ import li.cil.oc.util.SideTracker
|
||||
import li.cil.oc.util.UpdateCheck
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
@ -145,23 +147,36 @@ object EventHandler {
|
||||
ClientPacketSender.sendPetVisibility()
|
||||
}
|
||||
|
||||
lazy val eeprom = api.Items.get("eeprom")
|
||||
lazy val mcu = api.Items.get("microcontroller")
|
||||
lazy val navigationUpgrade = api.Items.get("navigationUpgrade")
|
||||
|
||||
@SubscribeEvent
|
||||
def onCrafting(e: ItemCraftedEvent) = {
|
||||
if (api.Items.get(e.crafting) == navigationUpgrade) {
|
||||
Option(api.Driver.driverFor(e.crafting)).foreach(driver =>
|
||||
for (i <- 0 until e.craftMatrix.getSizeInventory) {
|
||||
val stack = e.craftMatrix.getStackInSlot(i)
|
||||
if (stack != null && api.Items.get(stack) == navigationUpgrade) {
|
||||
// Restore the map currently used in the upgrade.
|
||||
val nbt = driver.dataTag(stack)
|
||||
val map = ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "map"))
|
||||
if (map != null && !e.player.inventory.addItemStackToInventory(map)) {
|
||||
e.player.dropPlayerItemWithRandomChoice(map, false)
|
||||
}
|
||||
}
|
||||
})
|
||||
recraft(e, navigationUpgrade, stack => {
|
||||
// Restore the map currently used in the upgrade.
|
||||
Option(api.Driver.driverFor(e.crafting)) match {
|
||||
case Some(driver) => Option(ItemUtils.loadStack(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map")))
|
||||
case _ => None
|
||||
}
|
||||
})
|
||||
|
||||
recraft(e, mcu, stack => {
|
||||
// Restore EEPROM currently used in microcontroller.
|
||||
new ItemUtils.MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
})
|
||||
}
|
||||
|
||||
private def recraft(e: ItemCraftedEvent, item: ItemInfo, callback: ItemStack => Option[ItemStack]): Unit = {
|
||||
if (api.Items.get(e.crafting) == item) {
|
||||
for (slot <- 0 until e.craftMatrix.getSizeInventory) {
|
||||
val stack = e.craftMatrix.getStackInSlot(slot)
|
||||
if (api.Items.get(stack) == item) {
|
||||
callback(stack).foreach(extra => if (!e.player.inventory.addItemStackToInventory(extra)) {
|
||||
e.player.dropPlayerItemWithRandomChoice(extra, false)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
99
src/main/scala/li/cil/oc/common/block/Microcontroller.scala
Normal file
99
src/main/scala/li/cil/oc/common/block/Microcontroller.scala
Normal file
@ -0,0 +1,99 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class Microcontroller extends RedstoneAware with traits.PowerAcceptor {
|
||||
override protected def customTextures = Array(
|
||||
Some("MicrocontrollerTop"),
|
||||
Some("MicrocontrollerTop"),
|
||||
Some("MicrocontrollerSide"),
|
||||
Some("MicrocontrollerFront"),
|
||||
Some("MicrocontrollerSide"),
|
||||
Some("MicrocontrollerSide")
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def getPickBlock(target: MovingObjectPosition, world: World, x: Int, y: Int, z: Int) =
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case mcu: tileentity.Microcontroller => mcu.info.copyItemStack()
|
||||
case _ => null
|
||||
}
|
||||
|
||||
// Custom drop logic for NBT tagged item stack.
|
||||
override def getDrops(world: World, x: Int, y: Int, z: Int, metadata: Int, fortune: Int) = new java.util.ArrayList[ItemStack]()
|
||||
|
||||
override def onBlockPreDestroy(world: World, x: Int, y: Int, z: Int, metadata: Int) {}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||
super.tooltipTail(metadata, stack, player, tooltip, advanced)
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val info = new ItemUtils.MicrocontrollerData(stack)
|
||||
for (component <- info.components) {
|
||||
tooltip.add("- " + component.getDisplayName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def energyThroughput = Settings.get.caseRate(Tier.One)
|
||||
|
||||
override def createTileEntity(world: World, metadata: Int) = new tileentity.Microcontroller()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
|
||||
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking && !Wrench.holdsApplicableWrench(player, x, y, z)) {
|
||||
if (!world.isRemote) {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
if (mcu.machine.isRunning) mcu.machine.stop()
|
||||
else mcu.machine.start()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
||||
override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, entity: EntityLivingBase, stack: ItemStack) {
|
||||
super.onBlockPlacedBy(world, x, y, z, entity, stack)
|
||||
if (!world.isRemote) world.getTileEntity(x, y, z) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
mcu.info.load(stack)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
override def removedByPlayer(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, willHarvest: Boolean): Boolean = {
|
||||
if (!world.isRemote) {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
mcu.saveComponents()
|
||||
dropBlockAsItem(world, x, y, z, mcu.info.createItemStack())
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
super.removedByPlayer(world, player, x, y, z, willHarvest)
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ object Blocks {
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Keyboard], Settings.namespace + "keyboard")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Hologram], Settings.namespace + "hologram")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Geolyzer], Settings.namespace + "geolyzer")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Microcontroller], Settings.namespace + "microcontroller")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.MotionSensor], Settings.namespace + "motion_sensor")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerConverter], Settings.namespace + "power_converter")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerDistributor], Settings.namespace + "power_distributor")
|
||||
@ -33,6 +34,7 @@ object Blocks {
|
||||
|
||||
// These are purely for converting existing blocks in delegator format to the new,
|
||||
// one block type per block format.
|
||||
// TODO Remove in 1.5
|
||||
GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "simple")
|
||||
GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "simple_redstone")
|
||||
GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "special")
|
||||
@ -86,5 +88,6 @@ object Blocks {
|
||||
|
||||
// v1.4.2
|
||||
Recipes.addBlock(new Raid(), "raid", "oc:raid")
|
||||
Items.registerBlock(new Microcontroller(), "microcontroller")
|
||||
}
|
||||
}
|
||||
|
@ -307,9 +307,9 @@ object Items extends ItemAPI {
|
||||
if (Mods.AppliedEnergistics2.isAvailable) {
|
||||
Recipes.addItem(new item.AppliedEnergisticsP2PTunnel(), "appengTunnel")
|
||||
}
|
||||
|
||||
val eeprom = new item.EEPROM()
|
||||
Recipes.addItem(eeprom, "eeprom", "oc:eeprom")
|
||||
Recipes.addRecipe(createLuaBios(), "luaBios")
|
||||
Recipes.addMultiItem(new item.MicrocontrollerCase(multi), "microcontrollerCase", "oc:microcontrollerCase")
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class MicrocontrollerCase(val parent: Delegator) extends Delegate
|
@ -7,6 +7,7 @@ import li.cil.oc.api
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.inventory.InventoryCrafting
|
||||
@ -16,6 +17,8 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object ExtendedRecipe {
|
||||
private lazy val eeprom = api.Items.get("eeprom")
|
||||
private lazy val mcu = api.Items.get("microcontroller")
|
||||
private lazy val navigationUpgrade = api.Items.get("navigationUpgrade")
|
||||
private lazy val linkedCard = api.Items.get("linkedCard")
|
||||
private lazy val floppy = api.Items.get("floppy")
|
||||
@ -30,8 +33,8 @@ object ExtendedRecipe {
|
||||
def addNBTToResult(craftedStack: ItemStack, inventory: InventoryCrafting): ItemStack = {
|
||||
if (api.Items.get(craftedStack) == navigationUpgrade) {
|
||||
Option(api.Driver.driverFor(craftedStack)).foreach(driver =>
|
||||
for (i <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(i)
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
if (stack != null && stack.getItem == net.minecraft.init.Items.filled_map) {
|
||||
// Store information of the map used for crafting in the result.
|
||||
val nbt = driver.dataTag(craftedStack)
|
||||
@ -55,8 +58,8 @@ object ExtendedRecipe {
|
||||
craftedStack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
val nbt = craftedStack.getTagCompound
|
||||
for (i <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(i)
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
if (stack != null) {
|
||||
if (api.Items.get(stack) == floppy && stack.hasTagCompound) {
|
||||
val oldData = stack.getTagCompound
|
||||
@ -68,6 +71,29 @@ object ExtendedRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
if (api.Items.get(craftedStack) == mcu) {
|
||||
// Find old Microcontroller.
|
||||
(0 until inventory.getSizeInventory).map(inventory.getStackInSlot).find(api.Items.get(_) == mcu) match {
|
||||
case Some(oldMcu) =>
|
||||
val data = new ItemUtils.MicrocontrollerData(oldMcu)
|
||||
|
||||
// Remove old EEPROM.
|
||||
val oldRom = data.components.filter(api.Items.get(_) == eeprom)
|
||||
data.components = data.components.diff(oldRom)
|
||||
|
||||
// Insert new EEPROM.
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
if (api.Items.get(stack) == eeprom) {
|
||||
data.components :+= stack
|
||||
}
|
||||
}
|
||||
|
||||
data.save(craftedStack)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
craftedStack
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,10 @@ object Recipes {
|
||||
result.setTagCompound(tag)
|
||||
GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(result, floppy, dye))
|
||||
}
|
||||
|
||||
// Microcontroller recrafting.
|
||||
val mcu = api.Items.get("microcontroller").createItemStack(1)
|
||||
GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(mcu, mcu, api.Items.get("eeprom").createItemStack(1)))
|
||||
}
|
||||
catch {
|
||||
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)
|
||||
|
@ -0,0 +1,67 @@
|
||||
package li.cil.oc.common.template
|
||||
|
||||
import cpw.mods.fml.common.event.FMLInterModComms
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.template.TabletTemplate.hasComponent
|
||||
import li.cil.oc.common.template.TabletTemplate.hasFileSystem
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.nbt.NBTTagList
|
||||
|
||||
object MicrocontrollerTemplate extends Template {
|
||||
override protected val suggestedComponents = Array(
|
||||
"BIOS" -> hasComponent("eeprom") _)
|
||||
|
||||
override protected def hostClass = classOf[internal.Microcontroller]
|
||||
|
||||
def select(stack: ItemStack) = api.Items.get(stack) == api.Items.get("microcontrollerCase")
|
||||
|
||||
def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory)
|
||||
|
||||
def assemble(inventory: IInventory) = {
|
||||
val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot)
|
||||
val data = new ItemUtils.MicrocontrollerData()
|
||||
data.components = items.drop(1).filter(_ != null).toArray
|
||||
val stack = api.Items.get("microcontroller").createItemStack(1)
|
||||
data.save(stack)
|
||||
val energy = Settings.get.microcontrollerBaseCost + complexity(inventory) * Settings.get.microcontrollerComplexityCost
|
||||
|
||||
Array(stack, double2Double(energy))
|
||||
}
|
||||
|
||||
def register() {
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("name", "Microcontroller")
|
||||
nbt.setString("select", "li.cil.oc.common.template.MicrocontrollerTemplate.select")
|
||||
nbt.setString("validate", "li.cil.oc.common.template.MicrocontrollerTemplate.validate")
|
||||
nbt.setString("assemble", "li.cil.oc.common.template.MicrocontrollerTemplate.assemble")
|
||||
nbt.setString("hostClass", "li.cil.oc.api.internal.Microcontroller")
|
||||
|
||||
val upgradeSlots = new NBTTagList()
|
||||
upgradeSlots.appendTag(Map("tier" -> Tier.Any))
|
||||
nbt.setTag("upgradeSlots", upgradeSlots)
|
||||
|
||||
val componentSlots = new NBTTagList()
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Card, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(new NBTTagCompound())
|
||||
componentSlots.appendTag(Map("type" -> Slot.CPU, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(Map("type" -> Slot.Memory, "tier" -> Tier.One))
|
||||
componentSlots.appendTag(new NBTTagCompound())
|
||||
componentSlots.appendTag(Map("type" -> Slot.EEPROM, "tier" -> Tier.Any))
|
||||
nbt.setTag("componentSlots", componentSlots)
|
||||
|
||||
FMLInterModComms.sendMessage("OpenComputers", "registerAssemblerTemplate", nbt)
|
||||
}
|
||||
|
||||
override protected def maxComplexity(inventory: IInventory) = 4
|
||||
|
||||
override protected def caseTier(inventory: IInventory) = if (select(inventory.getStackInSlot(0))) Tier.One else Tier.None
|
||||
}
|
@ -93,7 +93,7 @@ abstract class Template {
|
||||
acc += (Option(api.Driver.driverFor(stack, hostClass)) match {
|
||||
case Some(driver: Processor) => 0 // CPUs are exempt, since they control the limit.
|
||||
case Some(driver: Container) => (1 + driver.tier(stack)) * 2
|
||||
case Some(driver) => 1 + driver.tier(stack)
|
||||
case Some(driver) if driver.slot(stack) != Slot.EEPROM => 1 + driver.tier(stack)
|
||||
case _ => 0
|
||||
})
|
||||
}
|
||||
|
@ -95,9 +95,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
else if (api.Items.get(stack) == api.Items.get("server2")) enqueueServer(stack, 1)
|
||||
else if (api.Items.get(stack) == api.Items.get("server3")) enqueueServer(stack, 2)
|
||||
else if (api.Items.get(stack) == api.Items.get("tablet")) enqueueTablet(stack)
|
||||
else if (api.Items.get(stack) == api.Items.get("navigationUpgrade")) {
|
||||
enqueueNavigationUpgrade(stack)
|
||||
}
|
||||
else if (api.Items.get(stack) == api.Items.get("microcontroller")) enqueueMicrocontroller(stack)
|
||||
else if (api.Items.get(stack) == api.Items.get("navigationUpgrade")) enqueueNavigationUpgrade(stack)
|
||||
else queue ++= getIngredients(stack)
|
||||
totalRequiredEnergy = queue.size * Settings.get.disassemblerItemCost
|
||||
}
|
||||
@ -136,6 +135,12 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
node.changeBuffer(info.energy)
|
||||
}
|
||||
|
||||
private def enqueueMicrocontroller(mcu: ItemStack) {
|
||||
val info = new ItemUtils.MicrocontrollerData(mcu)
|
||||
queue += api.Items.get("microcontrollerCase").createItemStack(1)
|
||||
queue ++= info.components
|
||||
}
|
||||
|
||||
private def enqueueNavigationUpgrade(stack: ItemStack) {
|
||||
val info = new ItemUtils.NavigationUpgradeData(stack)
|
||||
val parts = getIngredients(stack)
|
||||
@ -243,7 +248,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
override def getInventoryStackLimit = 64
|
||||
|
||||
override def isItemValidForSlot(i: Int, stack: ItemStack) =
|
||||
api.Items.get(stack) == api.Items.get("robot") ||
|
||||
((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && getIngredients(stack).nonEmpty) ||
|
||||
api.Items.get(stack) == api.Items.get("robot") ||
|
||||
api.Items.get(stack) == api.Items.get("tablet") ||
|
||||
((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && getIngredients(stack).nonEmpty)
|
||||
api.Items.get(stack) == api.Items.get("microcontroller")
|
||||
}
|
||||
|
176
src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala
Normal file
176
src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala
Normal file
@ -0,0 +1,176 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.api.driver.item.Memory
|
||||
import li.cil.oc.api.driver.item.Processor
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.api.machine.Architecture
|
||||
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.Connector
|
||||
import li.cil.oc.api.network.Message
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class Microcontroller extends traits.PowerAcceptor with traits.Computer with internal.Microcontroller {
|
||||
val info = new ItemUtils.MicrocontrollerData()
|
||||
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("microcontroller").
|
||||
withConnector().
|
||||
create()
|
||||
|
||||
private val snooperNode = api.Network.newNode(this, Visibility.Network).create()
|
||||
|
||||
override protected def runSound = None // Microcontrollers are silent.
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override protected def hasConnector(side: ForgeDirection) = side != facing
|
||||
|
||||
override protected def connector(side: ForgeDirection) = Option(if (side != facing && machine != null) machine.node.asInstanceOf[Connector] else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.caseRate(Tier.One)
|
||||
|
||||
override def getWorld = world
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def cpuArchitecture: Class[_ <: Architecture] = info.components.map(stack => (stack, Driver.driverFor(stack, getClass))).collectFirst {
|
||||
case (stack, driver: Processor) if driver.slot(stack) == Slot.CPU => driver.architecture(stack)
|
||||
}.orNull
|
||||
|
||||
override def callBudget = info.components.foldLeft(0.0)((sum, item) => sum + (Option(item) match {
|
||||
case Some(stack) => Option(Driver.driverFor(stack, getClass)) match {
|
||||
case Some(driver: Processor) if driver.slot(stack) == Slot.CPU => Settings.get.callBudgets(driver.tier(stack))
|
||||
case _ => 0
|
||||
}
|
||||
case _ => 0
|
||||
}))
|
||||
|
||||
override def installedMemory = info.components.foldLeft(0)((sum, item) => sum + (Option(item) match {
|
||||
case Some(stack) => Option(Driver.driverFor(stack, getClass)) match {
|
||||
case Some(driver: Memory) => driver.amount(stack)
|
||||
case _ => 0
|
||||
}
|
||||
case _ => 0
|
||||
}))
|
||||
|
||||
override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address))
|
||||
|
||||
def maxComponents = 32
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Callback(doc = """function():boolean -- Starts the microcontroller. Returns true if the state changed.""")
|
||||
def start(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(!machine.isPaused && machine.start())
|
||||
|
||||
@Callback(doc = """function():boolean -- Stops the microcontroller. Returns true if the state changed.""")
|
||||
def stop(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(machine.stop())
|
||||
|
||||
@Callback(direct = true, doc = """function():boolean -- Returns whether the microcontroller is running.""")
|
||||
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(machine.isRunning)
|
||||
|
||||
@Callback(direct = true, doc = """function():string -- Returns the reason the microcontroller crashed, if applicable.""")
|
||||
def lastError(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(machine.lastError)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def canUpdate = isServer
|
||||
|
||||
override def updateEntity() {
|
||||
super.updateEntity()
|
||||
|
||||
// Pump energy into the internal network.
|
||||
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
machine.node match {
|
||||
case connector: Connector =>
|
||||
val demand = connector.globalBufferSize - connector.globalBuffer
|
||||
val available = demand + node.changeBuffer(-demand)
|
||||
connector.changeBuffer(available)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onConnect(node: Node) {
|
||||
if (node == this.node) {
|
||||
api.Network.joinNewNetwork(machine.node)
|
||||
machine.node.connect(snooperNode)
|
||||
machine.setCostPerTick(Settings.get.microcontrollerCost)
|
||||
}
|
||||
super.onConnect(node)
|
||||
}
|
||||
|
||||
override def onMessage(message: Message) {
|
||||
super.onMessage(message)
|
||||
if (message.name == "network.message") {
|
||||
if (message.source.network == snooperNode.network)
|
||||
node.sendToReachable(message.name, message.data: _*)
|
||||
else
|
||||
snooperNode.sendToReachable(message.name, message.data: _*)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def connectItemNode(node: Node) {
|
||||
if (machine.node != null && node != null) {
|
||||
machine.node.connect(node)
|
||||
}
|
||||
}
|
||||
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
// Load info before inventory and such, to avoid initializing components
|
||||
// to empty inventory.
|
||||
info.load(nbt.getCompoundTag(Settings.namespace + "info"))
|
||||
super.readFromNBT(nbt)
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
nbt.setNewCompoundTag(Settings.namespace + "info", info.save)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@SideOnly(Side.CLIENT) override
|
||||
def readFromNBTForClient(nbt: NBTTagCompound) {
|
||||
info.load(nbt.getCompoundTag("info"))
|
||||
super.readFromNBTForClient(nbt)
|
||||
}
|
||||
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForClient(nbt)
|
||||
nbt.setNewCompoundTag("info", info.save)
|
||||
}
|
||||
|
||||
override lazy val items = info.components.map(Option(_))
|
||||
|
||||
override def getSizeInventory = info.components.length
|
||||
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) = false
|
||||
|
||||
// Nope.
|
||||
override def setInventorySlotContents(slot: Int, stack: ItemStack) {}
|
||||
|
||||
// Nope.
|
||||
override def decrStackSize(slot: Int, amount: Int) = null
|
||||
}
|
@ -41,6 +41,8 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
|
||||
private val _users = mutable.Set.empty[String]
|
||||
|
||||
protected def runSound = Option("computer_running")
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def canInteract(player: String) =
|
||||
@ -53,8 +55,10 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
def setRunning(value: Boolean): Unit = if (value != _isRunning) {
|
||||
_isRunning = value
|
||||
world.markBlockForUpdate(x, y, z)
|
||||
if (_isRunning) Sound.startLoop(this, "computer_running", 0.5f, 50 + world.rand.nextInt(50))
|
||||
else Sound.stopLoop(this)
|
||||
runSound.foreach(sound =>
|
||||
if (_isRunning) Sound.startLoop(this, sound, 0.5f, 50 + world.rand.nextInt(50))
|
||||
else Sound.stopLoop(this)
|
||||
)
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -158,7 +162,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
_isRunning = nbt.getBoolean("isRunning")
|
||||
_users.clear()
|
||||
_users ++= nbt.getTagList("users", NBT.TAG_STRING).map((tag: NBTTagString) => tag.func_150285_a_())
|
||||
if (_isRunning) Sound.startLoop(this, "computer_running", 0.5f, 1000 + world.rand.nextInt(2000))
|
||||
if (_isRunning) runSound.foreach(sound => Sound.startLoop(this, sound, 0.5f, 1000 + world.rand.nextInt(2000)))
|
||||
}
|
||||
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||
|
@ -1,11 +1,15 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.{OpenComputers, Settings, api}
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.Processor
|
||||
import li.cil.oc.api.machine.Architecture
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
@ -1,10 +1,13 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.{Settings, api}
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.Processor
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverComponentBus extends Item with Processor {
|
||||
|
@ -3,8 +3,10 @@ package li.cil.oc.integration.opencomputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.Container
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverContainerCard extends Item with Container {
|
||||
|
@ -3,8 +3,10 @@ package li.cil.oc.integration.opencomputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.Container
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverContainerUpgrade extends Item with Container {
|
||||
|
@ -14,7 +14,7 @@ object DriverEEPROM extends Item with HostAware with EnvironmentAware {
|
||||
isOneOf(stack, api.Items.get("eeprom"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isTablet(host))
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isTablet(host) || isMicrocontroller(host))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.EEPROM()
|
||||
|
||||
|
@ -1,16 +1,23 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.api.driver.{EnvironmentAware, EnvironmentHost}
|
||||
import li.cil.oc.{api, common}
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentAware
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier}
|
||||
import li.cil.oc.server.component
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverGraphicsCard extends Item with EnvironmentAware {
|
||||
object DriverGraphicsCard extends Item with HostAware with EnvironmentAware {
|
||||
override def worksWith(stack: ItemStack) =
|
||||
isOneOf(stack, api.Items.get("graphicsCard1"), api.Items.get("graphicsCard2"), api.Items.get("graphicsCard3"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && !isMicrocontroller(host)
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
|
||||
tier(stack) match {
|
||||
case Tier.One => new component.GraphicsCard.Tier1()
|
||||
|
@ -12,7 +12,7 @@ object DriverKeyboard extends Item with HostAware {
|
||||
isOneOf(stack, api.Items.get("keyboard"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && !isAdapter(host)
|
||||
worksWith(stack) && !isAdapter(host) && !isMicrocontroller(host)
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.Keyboard(host)
|
||||
|
||||
|
@ -20,7 +20,7 @@ object DriverRedstoneCard extends Item with HostAware with EnvironmentAware {
|
||||
override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("redstoneCard1"), api.Items.get("redstoneCard2"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host))
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isMicrocontroller(host))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
|
||||
host match {
|
||||
|
@ -14,7 +14,7 @@ object DriverScreen extends Item with HostAware with EnvironmentAware {
|
||||
isOneOf(stack, api.Items.get("screen1"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && !isTablet(host) && !isAdapter(host)
|
||||
worksWith(stack) && !isTablet(host) && !isAdapter(host) && !isMicrocontroller(host)
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = host match {
|
||||
case screen: tileentity.Screen if screen.tier > 0 => new component.Screen(screen)
|
||||
|
@ -3,8 +3,10 @@ package li.cil.oc.integration.opencomputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.server.component
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
|
@ -3,17 +3,24 @@ package li.cil.oc.integration.opencomputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver
|
||||
import li.cil.oc.api.driver.EnvironmentAware
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.inventory.DatabaseInventory
|
||||
import li.cil.oc.common.{Slot, Tier, item}
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.server.component
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverUpgradeDatabase extends Item with EnvironmentAware {
|
||||
object DriverUpgradeDatabase extends Item with HostAware with EnvironmentAware {
|
||||
override def worksWith(stack: ItemStack) =
|
||||
isOneOf(stack, api.Items.get("databaseUpgrade1"), api.Items.get("databaseUpgrade2"), api.Items.get("databaseUpgrade3"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && !isMicrocontroller(host)
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: driver.EnvironmentHost) =
|
||||
new component.UpgradeDatabase(new DatabaseInventory {
|
||||
override def tier = DriverUpgradeDatabase.tier(stack)
|
||||
|
@ -15,7 +15,7 @@ object DriverUpgradeNavigation extends Item with HostAware with EnvironmentAware
|
||||
isOneOf(stack, api.Items.get("navigationUpgrade"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && isRotatable(host)
|
||||
worksWith(stack) && (isRotatable(host) && !isMicrocontroller(host))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
|
||||
host match {
|
||||
|
@ -1,12 +1,15 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.{EnvironmentAware, EnvironmentHost}
|
||||
import li.cil.oc.api.driver.EnvironmentAware
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.api.internal.{Adapter, Rotatable}
|
||||
import li.cil.oc.api.internal.Adapter
|
||||
import li.cil.oc.api.internal.Rotatable
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.server.component.{UpgradeSignInAdapter, UpgradeSignInRotatable}
|
||||
import li.cil.oc.server.component.UpgradeSignInAdapter
|
||||
import li.cil.oc.server.component.UpgradeSignInRotatable
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverUpgradeSign extends Item with HostAware with EnvironmentAware {
|
||||
@ -14,7 +17,7 @@ object DriverUpgradeSign extends Item with HostAware with EnvironmentAware {
|
||||
isOneOf(stack, api.Items.get("signUpgrade"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && (isRotatable(host) || isAdapter(host))
|
||||
worksWith(stack) && (isAdapter(host) || isRotatable(host))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
|
||||
host match {
|
||||
|
@ -19,5 +19,5 @@ object DriverUpgradeSolarGenerator extends Item with HostAware {
|
||||
|
||||
override def slot(stack: ItemStack) = Slot.Upgrade
|
||||
|
||||
override def tier(stack: ItemStack) = Tier.Three
|
||||
override def tier(stack: ItemStack) = Tier.Two
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ trait Item extends driver.Item {
|
||||
protected def isServer(host: Class[_ <: EnvironmentHost]) = classOf[internal.Server].isAssignableFrom(host)
|
||||
|
||||
protected def isTablet(host: Class[_ <: EnvironmentHost]) = classOf[internal.Tablet].isAssignableFrom(host)
|
||||
|
||||
protected def isMicrocontroller(host: Class[_ <: EnvironmentHost]) = classOf[internal.Microcontroller].isAssignableFrom(host)
|
||||
}
|
||||
|
||||
object Item {
|
||||
|
@ -10,6 +10,7 @@ import li.cil.oc.common.asm.SimpleComponentTickHandler
|
||||
import li.cil.oc.common.event._
|
||||
import li.cil.oc.common.item.Tablet
|
||||
import li.cil.oc.common.recipe.Recipes
|
||||
import li.cil.oc.common.template.MicrocontrollerTemplate
|
||||
import li.cil.oc.common.template.RobotTemplate
|
||||
import li.cil.oc.common.template.TabletTemplate
|
||||
import li.cil.oc.integration.ModProxy
|
||||
@ -22,6 +23,7 @@ object ModOpenComputers extends ModProxy {
|
||||
override def getMod = Mods.OpenComputers
|
||||
|
||||
override def initialize() {
|
||||
MicrocontrollerTemplate.register()
|
||||
RobotTemplate.register()
|
||||
TabletTemplate.register()
|
||||
|
||||
|
@ -16,7 +16,7 @@ object DriverAbstractBusCard extends Item with HostAware with EnvironmentAware {
|
||||
isOneOf(stack, api.Items.get("abstractBusCard"))
|
||||
|
||||
override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]) =
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host))
|
||||
worksWith(stack) && (isComputer(host) || isRobot(host) || isServer(host) || isMicrocontroller(host))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = if (Mods.StargateTech2.isAvailable) host match {
|
||||
case device: IBusDevice => new component.AbstractBusCard(device)
|
||||
|
@ -26,6 +26,9 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
|
||||
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
||||
def set(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||
return result(Unit, "not enough energy")
|
||||
}
|
||||
val newData = args.checkByteArray(0)
|
||||
if (newData.length > 4 * 1024) throw new IllegalArgumentException("not enough space")
|
||||
data = newData
|
||||
|
@ -13,6 +13,7 @@ import li.cil.oc.common.tileentity.traits.RedstoneAware
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
@Optional.InterfaceList(Array(
|
||||
new Optional.Interface(iface = "codechicken.wirelessredstone.core.WirelessReceivingDevice", modid = Mods.IDs.WirelessRedstoneCBE),
|
||||
@ -74,7 +75,7 @@ trait RedstoneWireless extends Redstone[RedstoneAware] with WirelessReceivingDev
|
||||
override def updateDevice(frequency: Int, on: Boolean) {
|
||||
if (frequency == wirelessFrequency && on != wirelessInput) {
|
||||
wirelessInput = on
|
||||
// TODO signal to computer
|
||||
node.sendToReachable("computer.signal", "redstone_changed", "wireless")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ class UpgradePiston(val host: Rotatable with EnvironmentHost) extends prefab.Man
|
||||
|
||||
private lazy val tryExtend = ReflectionHelper.findMethod(classOf[BlockPistonBase], null, Array("tryExtend", "func_150079_i", "i"), classOf[World], classOf[Int], classOf[Int], classOf[Int], classOf[Int])
|
||||
|
||||
@Callback(doc = """function(side:number):boolean -- Tries to push the block in front of the container of the upgrade.""")
|
||||
@Callback(doc = """function():boolean -- Tries to push the block in front of the container of the upgrade.""")
|
||||
def push(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val hostPos = BlockPosition(host)
|
||||
val blockPos = hostPos.offset(host.facing)
|
||||
|
@ -10,7 +10,6 @@ import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.block.DelegatorConverter
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.integration.opencomputers.DriverScreen
|
||||
import li.cil.oc.integration.opencomputers.DriverUpgradeExperience
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import net.minecraft.item.ItemMap
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -49,6 +48,85 @@ object ItemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
class MicrocontrollerData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var components = Array.empty[ItemStack]
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(loadStack)
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
nbt.setNewTagList(Settings.namespace + "components", components.toIterable)
|
||||
}
|
||||
|
||||
def createItemStack() = {
|
||||
val stack = api.Items.get("microcontroller").createItemStack(1)
|
||||
save(stack)
|
||||
stack
|
||||
}
|
||||
|
||||
def copyItemStack() = {
|
||||
val stack = createItemStack()
|
||||
// Forget all node addresses and so on. This is used when 'picking' a
|
||||
// microcontroller in creative mode.
|
||||
val newInfo = new MicrocontrollerData(stack)
|
||||
newInfo.components.foreach(cs => Option(api.Driver.driverFor(cs)) match {
|
||||
case Some(driver) if driver == DriverScreen =>
|
||||
val nbt = driver.dataTag(cs)
|
||||
for (tagName <- nbt.func_150296_c().toArray) {
|
||||
nbt.removeTag(tagName.asInstanceOf[String])
|
||||
}
|
||||
case _ =>
|
||||
})
|
||||
newInfo.save(stack)
|
||||
stack
|
||||
}
|
||||
}
|
||||
|
||||
class NavigationUpgradeData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var map = new ItemStack(net.minecraft.init.Items.filled_map)
|
||||
|
||||
def mapData(world: World) = try map.getItem.asInstanceOf[ItemMap].getMapData(map, world) catch {
|
||||
case _: Throwable => throw new Exception("invalid map")
|
||||
}
|
||||
|
||||
override def load(stack: ItemStack) {
|
||||
if (stack.hasTagCompound) {
|
||||
load(stack.getTagCompound.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(stack: ItemStack) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
save(stack.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
if (nbt.hasKey(Settings.namespace + "map")) {
|
||||
map = loadStack(nbt.getCompoundTag(Settings.namespace + "map"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
if (map != null) {
|
||||
nbt.setNewCompoundTag(Settings.namespace + "map", map.writeToNBT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RobotData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
@ -151,44 +229,6 @@ object ItemUtils {
|
||||
def randomName = if (names.length > 0) names((math.random * names.length).toInt) else "Robot"
|
||||
}
|
||||
|
||||
class NavigationUpgradeData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var map = new ItemStack(net.minecraft.init.Items.filled_map)
|
||||
|
||||
def mapData(world: World) = try map.getItem.asInstanceOf[ItemMap].getMapData(map, world) catch {
|
||||
case _: Throwable => throw new Exception("invalid map")
|
||||
}
|
||||
|
||||
override def load(stack: ItemStack) {
|
||||
if (stack.hasTagCompound) {
|
||||
load(stack.getTagCompound.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(stack: ItemStack) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
save(stack.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
if (nbt.hasKey(Settings.namespace + "map")) {
|
||||
map = loadStack(nbt.getCompoundTag(Settings.namespace + "map"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
if (map != null) {
|
||||
nbt.setNewCompoundTag(Settings.namespace + "map", map.writeToNBT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TabletData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
|
Loading…
x
Reference in New Issue
Block a user