mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-28 07:25:35 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into OC1.5-MC1.7.10
Conflicts: build.properties
This commit is contained in:
commit
30f23adf35
@ -1,7 +1,7 @@
|
||||
minecraft.version=1.7.10
|
||||
forge.version=10.13.2.1236
|
||||
|
||||
oc.version=1.5.0
|
||||
oc.version=1.5.1
|
||||
oc.subversion=
|
||||
|
||||
ae2.version=rv1-stable-1
|
||||
|
@ -195,7 +195,7 @@ oc:tooltip.Cable=Ein billiger Weg, verschiedene Blöcke miteinander zu verbinden
|
||||
oc:tooltip.Capacitor=Speichert Energie für spätere Verwendung. Kann extrem schnell befüllt und entleert werden.
|
||||
oc:tooltip.CardBase=Wie der Name schon sagt, werden alle Erweiterungskarten hieraus hergestellt.
|
||||
oc:tooltip.Case=Das Computergehäuse ist der essentielle Grundbaustein für einen Computer. §fErweiterungskarten§7, §fRAM§7 und §fFestplatten§7 können in einem Gehäuse installiert werden.[nl] Slots: §f%s§7
|
||||
oc:tooltip.Charger=Lädt Roboter mit Energie aus Kondensatoren auf. Die Ladegeschwindigkeit hängt vom eingehenden §fRedstonesignal§7 ab, wobei kein Signal "nicht laden" und ein Signal mit maximaler Stärke "schnellstmöglich laden" heißt.
|
||||
oc:tooltip.Charger=Lädt Roboter mit Energie aus Kondensatoren auf. Die Ladegeschwindigkeit hängt vom eingehenden §fRedstonesignal§7 ab, wobei kein Signal "nicht laden" und ein Signal mit maximaler Stärke "schnellstmöglich laden" heißt. Erlaubt es auch Tablets zu laden, und ermöglicht Zugriff auf Festplatten in Tablets.
|
||||
oc:tooltip.CircuitBoard=Mühsam ernährt sich das Eichhörnchen. Wenn es groß wird, wird es mal eine gedruckte Leiterplatte.
|
||||
oc:tooltip.ControlUnit=Klingt wichtig, ist es auch. Man baut daraus immerhin CPUs. Wie könnte es da nicht wichtig sein.
|
||||
oc:tooltip.ComponentBus=Diese Erweiterung erlaubt es es Servern, mit noch mehr Komponenten gleichzeitig zu kommunizieren, ähnlich wie CPUs.[nl] Supported components: §f%s§7
|
||||
|
@ -219,7 +219,7 @@ oc:tooltip.Cable=A cheap way of connecting blocks.
|
||||
oc:tooltip.Capacitor=Stores energy for later use. Can be filled and emptied very quickly.
|
||||
oc:tooltip.CardBase=As the name indicates, this is the basic building block for all expansion cards.
|
||||
oc:tooltip.Case=The Computer Case is the basic building block for computers and houses the computer's §fextension cards§7, §fRAM§7 and §fhard disks§7.[nl] Slots: §f%s§7
|
||||
oc:tooltip.Charger=Transfers energy from capacitors into adjacent robots and drones. The transfer rate depends on the incoming §fredstone signal§7, where no signal means don't charge devices, and maximum strength means charge at full speed.
|
||||
oc:tooltip.Charger=Transfers energy from capacitors into adjacent robots and drones. The transfer rate depends on the incoming §fredstone signal§7, where no signal means don't charge devices, and maximum strength means charge at full speed. Can also be used to charge tablets and access hard drives in tablets.
|
||||
oc:tooltip.CircuitBoard=Now we're getting somewhere. Can be etched to obtain a printed circuit board.
|
||||
oc:tooltip.ControlUnit=This is the unit that... controls... stuff. You need it to build a CPU. So yeah, totally important.
|
||||
oc:tooltip.ComponentBus=This expansion allows servers to communicate with more components at the same time, similar to how CPUs do.[nl] Supported components: §f%s§7
|
||||
|
@ -1,8 +1,8 @@
|
||||
local rc = require('rc')
|
||||
|
||||
local args = table.pack(...)
|
||||
if args.n < 2 then
|
||||
io.write("Usage: rc <service> <command> [args...]")
|
||||
if args.n < 1 then
|
||||
io.write("Usage: rc <service> [command] [args...]")
|
||||
return
|
||||
end
|
||||
|
||||
@ -11,3 +11,4 @@ local result, reason = rc.runCommand(table.unpack(args))
|
||||
if not result then
|
||||
io.stderr:write(reason .. "\n")
|
||||
end
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
local fs = require('filesystem')
|
||||
local serialization = require('serialization')
|
||||
|
||||
-- Keeps track of loaded scripts to retain local values between invocation
|
||||
-- of their command callbacks.
|
||||
@ -18,6 +19,19 @@ local function loadConfig()
|
||||
return nil, reason
|
||||
end
|
||||
|
||||
local function saveConfig(conf)
|
||||
local file, reason = io.open('/etc/rc.cfg', 'w')
|
||||
if not file then
|
||||
return nil, reason
|
||||
end
|
||||
for key, value in pairs(conf) do
|
||||
file:write(tostring(key) .. " = " .. serialization.serialize(value) .. "\n")
|
||||
end
|
||||
|
||||
file:close()
|
||||
return true
|
||||
end
|
||||
|
||||
function rc.load(name, args)
|
||||
if loaded[name] then
|
||||
return loaded[name]
|
||||
@ -39,14 +53,47 @@ function rc.unload(name)
|
||||
loaded[name] = nil
|
||||
end
|
||||
|
||||
local function rawRunCommand(name, cmd, args, ...)
|
||||
local function rawRunCommand(conf, name, cmd, args, ...)
|
||||
local result, what = rc.load(name, args)
|
||||
if result then
|
||||
if type(result[cmd]) == "function" then
|
||||
result, what = xpcall(result[cmd], debug.traceback, ...)
|
||||
if result then
|
||||
if not cmd then
|
||||
io.output():write("Commands for service " .. name .. "\n")
|
||||
for command, val in pairs(result) do
|
||||
if type(val) == "function" then
|
||||
io.output():write(tostring(command) .. " ")
|
||||
end
|
||||
end
|
||||
return true
|
||||
elseif type(result[cmd]) == "function" then
|
||||
res, what = xpcall(result[cmd], debug.traceback, ...)
|
||||
if res then
|
||||
return true
|
||||
end
|
||||
elseif cmd == "restart" and type(result["stop"]) == "function" and type(result["start"]) == "function" then
|
||||
res, what = xpcall(result["stop"], debug.traceback, ...)
|
||||
if res then
|
||||
res, what = xpcall(result["start"], debug.traceback, ...)
|
||||
if res then
|
||||
return true
|
||||
end
|
||||
end
|
||||
elseif cmd == "enable" then
|
||||
conf.enabled = conf.enabled or {}
|
||||
for _, _name in ipairs(conf.enabled) do
|
||||
if name == _name then
|
||||
return nil, "Service already enabled"
|
||||
end
|
||||
end
|
||||
conf.enabled[#conf.enabled + 1] = name
|
||||
return saveConfig(conf)
|
||||
elseif cmd == "disable" then
|
||||
conf.enabled = conf.enabled or {}
|
||||
for n, _name in ipairs(conf.enabled) do
|
||||
if name == _name then
|
||||
table.remove(conf.enabled, n)
|
||||
end
|
||||
end
|
||||
return saveConfig(conf)
|
||||
else
|
||||
what = "Command '" .. cmd .. "' not found in daemon '" .. name .. "'"
|
||||
end
|
||||
@ -59,7 +106,7 @@ function rc.runCommand(name, cmd, ...)
|
||||
if not conf then
|
||||
return nil, reason
|
||||
end
|
||||
return rawRunCommand(name, cmd, conf[name], ...)
|
||||
return rawRunCommand(conf, name, cmd, conf[name], ...)
|
||||
end
|
||||
|
||||
function rc.allRunCommand(cmd, ...)
|
||||
@ -69,9 +116,10 @@ function rc.allRunCommand(cmd, ...)
|
||||
end
|
||||
local results = {}
|
||||
for _, name in ipairs(conf.enabled or {}) do
|
||||
results[name] = table.pack(rawRunCommand(name, cmd, conf[name], ...))
|
||||
results[name] = table.pack(rawRunCommand(conf, name, cmd, conf[name], ...))
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
return rc
|
||||
|
||||
|
@ -5,7 +5,7 @@ SYNOPSIS
|
||||
df [FILE]...
|
||||
|
||||
DESCRIPTION
|
||||
`cp` allows copying single files on a filesystem and across filesystems.
|
||||
`df` outputs disk space information for the file systems containing the specified files. If no file names are given it returns the information for all currently mounted file systems.
|
||||
|
||||
EXAMPLES
|
||||
df
|
||||
|
@ -6,7 +6,7 @@ SYNOPSIS
|
||||
primary TYPE ADDRESS
|
||||
|
||||
DESCRIPTION
|
||||
This program allows reading the address of the current primary component of the specified type. It also allows chaning the current primary component for a specified type by providing the (abbreviated) address of the new primary component.
|
||||
This program allows reading the address of the current primary component of the specified type. It also allows changing the current primary component for a specified type by providing the (abbreviated) address of the new primary component.
|
||||
|
||||
EXAMPLES
|
||||
primary gpu
|
||||
|
@ -0,0 +1,36 @@
|
||||
NAME
|
||||
rc - Manage services
|
||||
|
||||
SYNOPSIS
|
||||
rc SERVICE COMMAND [ARGS...]
|
||||
|
||||
DESCRIPTION
|
||||
Controls services in /etc/rc.d/
|
||||
Common commands are start/stop/restart, there are also special commands enable/disable. A command is global function in executable file that is stored in /etc/rc.d/ directory. Service cen define own commands.
|
||||
|
||||
COMMANDS
|
||||
start
|
||||
This command starts specified service, executed automatically for all enbled services when system boots.
|
||||
|
||||
stop
|
||||
This command stops specified service.
|
||||
|
||||
restart
|
||||
This command restarts specified service. This command doesn't have to be implemented by services when start and stop commands are present.
|
||||
|
||||
enable
|
||||
This command enables specified service. Executing this command won't start the service. It's implemented by the rc library, but can be overridden by service.
|
||||
|
||||
disable
|
||||
This command disables specified service. Executing this command won't stop the service. It's implemented by the rc library, but can be overridden by service.
|
||||
|
||||
EXAMPLES
|
||||
rc example
|
||||
Lists commands of example service.
|
||||
|
||||
rc example start
|
||||
Starts example setvice.
|
||||
|
||||
rc example enable
|
||||
Makes example start on system boot.
|
||||
|
@ -15,6 +15,7 @@ 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.item.data.MicrocontrollerData
|
||||
import li.cil.oc.common.tileentity.Robot
|
||||
import li.cil.oc.common.tileentity.traits.power
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util
|
||||
@ -40,6 +41,12 @@ object EventHandler {
|
||||
|
||||
var totalWorldTicks = 0L
|
||||
|
||||
private val runningRobots = mutable.Set.empty[Robot]
|
||||
|
||||
def onRobotStart(robot: Robot): Unit = runningRobots += robot
|
||||
|
||||
def onRobotStopped(robot: Robot): Unit = runningRobots -= robot
|
||||
|
||||
def schedule(tileEntity: TileEntity) {
|
||||
if (SideTracker.isServer) pending.synchronized {
|
||||
pending += (() => Network.joinOrCreateNetwork(tileEntity))
|
||||
@ -108,6 +115,13 @@ object EventHandler {
|
||||
case t: Throwable => OpenComputers.log.warn("Error in scheduled tick action.", t)
|
||||
}
|
||||
})
|
||||
|
||||
val invalid = mutable.ArrayBuffer.empty[Robot]
|
||||
runningRobots.foreach(robot => {
|
||||
if (robot.isInvalid) invalid += robot
|
||||
else robot.machine.update()
|
||||
})
|
||||
runningRobots --= invalid
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@ -207,15 +221,7 @@ object EventHandler {
|
||||
// Presents!
|
||||
val present = api.Items.get("present").createItemStack(1)
|
||||
e.player.worldObj.playSoundAtEntity(e.player, "note.pling", 0.2f, 1f)
|
||||
if (e.player.inventory.addItemStackToInventory(present)) {
|
||||
e.player.inventory.markDirty()
|
||||
if (e.player.openContainer != null) {
|
||||
e.player.openContainer.detectAndSendChanges()
|
||||
}
|
||||
}
|
||||
else {
|
||||
e.player.dropPlayerItemWithRandomChoice(present, false)
|
||||
}
|
||||
InventoryUtils.addToPlayerInventory(present, e.player)
|
||||
}
|
||||
case _ => // Nope.
|
||||
}
|
||||
@ -236,9 +242,8 @@ object EventHandler {
|
||||
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)
|
||||
})
|
||||
callback(stack).foreach(extra =>
|
||||
InventoryUtils.addToPlayerInventory(extra, e.player))
|
||||
}
|
||||
}
|
||||
true
|
||||
|
@ -83,11 +83,16 @@ object SaveHandler {
|
||||
|
||||
def loadNBT(nbt: NBTTagCompound, name: String): NBTTagCompound = {
|
||||
val data = load(nbt, name)
|
||||
if (data.length > 0) {
|
||||
if (data.length > 0) try {
|
||||
val bais = new ByteArrayInputStream(data)
|
||||
val dis = new DataInputStream(bais)
|
||||
CompressedStreamTools.read(dis)
|
||||
}
|
||||
catch {
|
||||
case t: Throwable =>
|
||||
OpenComputers.log.warn("There was an error trying to restore a block's state from external data. This indicates that data was somehow corrupted.", t)
|
||||
new NBTTagCompound()
|
||||
}
|
||||
else new NBTTagCompound()
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.block
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
@ -10,6 +11,7 @@ import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -68,16 +70,32 @@ class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microc
|
||||
|
||||
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, BlockPosition(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 _ =>
|
||||
if (!Wrench.holdsApplicableWrench(player, BlockPosition(x, y, z))) {
|
||||
if (!player.isSneaking) {
|
||||
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
|
||||
}
|
||||
true
|
||||
else if (api.Items.get(player.getHeldItem) == api.Items.get("eeprom")) {
|
||||
if (!world.isRemote) {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
val newEeprom = player.inventory.decrStackSize(player.inventory.currentItem, 1)
|
||||
mcu.changeEEPROM(newEeprom) match {
|
||||
case Some(oldEeprom) => InventoryUtils.addToPlayerInventory(oldEeprom, player)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.container
|
||||
import li.cil.oc.client.gui.Icons
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.common.InventorySlots.InventorySlot
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.IInventory
|
||||
@ -36,8 +37,7 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index:
|
||||
if (SideTracker.isServer && getHasStack && !isItemValid(getStack)) {
|
||||
val stack = getStack
|
||||
putStack(null)
|
||||
player.inventory.addItemStackToInventory(stack)
|
||||
player.dropPlayerItemWithRandomChoice(stack, false)
|
||||
InventoryUtils.addToPlayerInventory(stack, player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ object RobotCommonHandler {
|
||||
val maxFlyingHeight = Settings.get.limitFlightHeight
|
||||
def isMovingDown = e.direction == ForgeDirection.DOWN
|
||||
def hasAdjacentBlock(pos: BlockPosition) = ForgeDirection.VALID_DIRECTIONS.exists(side => world.isSideSolid(pos.offset(side), side.getOpposite))
|
||||
def isWithinFlyingHeight(pos: BlockPosition) = (1 to maxFlyingHeight).exists(n => !world.isAirBlock(pos.offset(e.direction.getOpposite, n)))
|
||||
def isWithinFlyingHeight(pos: BlockPosition) = (1 to maxFlyingHeight).exists(n => !world.isAirBlock(pos.offset(ForgeDirection.DOWN, n)))
|
||||
val startPos = BlockPosition(robot)
|
||||
val targetPos = startPos.offset(e.direction)
|
||||
// New movement rules as of 1.5:
|
||||
|
@ -280,7 +280,7 @@ object Items extends ItemAPI {
|
||||
|
||||
def init() {
|
||||
multi = new item.Delegator() {
|
||||
lazy val configuredItems = Array(
|
||||
def configuredItems = Array(
|
||||
createOpenOS(),
|
||||
createLuaBios(),
|
||||
createConfiguredDrone(),
|
||||
|
@ -11,6 +11,8 @@ import net.minecraftforge.common.util.Constants.NBT
|
||||
trait Inventory extends IInventory {
|
||||
def items: Array[Option[ItemStack]]
|
||||
|
||||
def updateItems(slot: Int, stack: ItemStack) = items(slot) = Option(stack)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def getStackInSlot(slot: Int) =
|
||||
@ -45,7 +47,7 @@ trait Inventory extends IInventory {
|
||||
}
|
||||
|
||||
val oldStack = items(slot)
|
||||
items(slot) = None
|
||||
updateItems(slot, null)
|
||||
if (oldStack.isDefined) {
|
||||
onItemRemoved(slot, oldStack.get)
|
||||
}
|
||||
@ -53,7 +55,7 @@ trait Inventory extends IInventory {
|
||||
if (stack.stackSize > getInventoryStackLimit) {
|
||||
stack.stackSize = getInventoryStackLimit
|
||||
}
|
||||
items(slot) = Some(stack)
|
||||
updateItems(slot, stack)
|
||||
}
|
||||
|
||||
if (items(slot).isDefined) {
|
||||
@ -84,7 +86,7 @@ trait Inventory extends IInventory {
|
||||
nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
|
||||
val slot = slotNbt.getByte("slot")
|
||||
if (slot >= 0 && slot < items.length) {
|
||||
items(slot) = Option(ItemUtils.loadStack(slotNbt.getCompoundTag("item")))
|
||||
updateItems(slot, ItemUtils.loadStack(slotNbt.getCompoundTag("item")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ trait ItemStackInventory extends Inventory {
|
||||
// The item stack that provides the inventory.
|
||||
def container: ItemStack
|
||||
|
||||
lazy val items = Array.fill[Option[ItemStack]](getSizeInventory)(None)
|
||||
private lazy val inventory = Array.fill[Option[ItemStack]](getSizeInventory)(None)
|
||||
|
||||
override def items = inventory
|
||||
|
||||
// Initialize the list automatically if we have a container.
|
||||
if (container != null) {
|
||||
@ -24,14 +26,14 @@ trait ItemStackInventory extends Inventory {
|
||||
container.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
for (i <- 0 until items.length) {
|
||||
items(i) = None
|
||||
updateItems(i, null)
|
||||
}
|
||||
if (container.getTagCompound.hasKey(Settings.namespace + "items")) {
|
||||
val list = container.getTagCompound.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND)
|
||||
for (i <- 0 until (list.tagCount min items.length)) {
|
||||
val tag = list.getCompoundTagAt(i)
|
||||
if (!tag.hasNoTags) {
|
||||
items(i) = Option(ItemUtils.loadStack(tag))
|
||||
updateItems(i, ItemUtils.loadStack(tag))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
|
||||
class EEPROM extends SimpleItem {
|
||||
override def doesSneakBypassUse(world: World, x: Int, y: Int, z: Int, player: EntityPlayer): Boolean = true
|
||||
|
||||
override def getItemStackDisplayName(stack: ItemStack): String = {
|
||||
if (stack.hasTagCompound) {
|
||||
val tag = stack.getTagCompound
|
||||
|
@ -4,6 +4,7 @@ import java.util.Random
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -20,15 +21,7 @@ class Present(val parent: Delegator) extends Delegate {
|
||||
if (!world.isRemote) {
|
||||
world.playSoundAtEntity(player, "random.levelup", 0.2f, 1f)
|
||||
val present = Present.nextPresent()
|
||||
if (player.inventory.addItemStackToInventory(present)) {
|
||||
player.inventory.markDirty()
|
||||
if (player.openContainer != null) {
|
||||
player.openContainer.detectAndSendChanges()
|
||||
}
|
||||
}
|
||||
else {
|
||||
player.dropPlayerItemWithRandomChoice(present, false)
|
||||
}
|
||||
InventoryUtils.addToPlayerInventory(present, player)
|
||||
}
|
||||
}
|
||||
stack
|
||||
|
@ -17,20 +17,26 @@ class MicrocontrollerData extends ItemData {
|
||||
|
||||
var tier = Tier.One
|
||||
|
||||
var components = Array.empty[ItemStack]
|
||||
var components = Array[ItemStack](null)
|
||||
|
||||
var storedEnergy = 0
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
tier = nbt.getByte(Settings.namespace + "tier")
|
||||
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack)
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack).filter(_ != null)
|
||||
storedEnergy = nbt.getInteger(Settings.namespace + "storedEnergy")
|
||||
|
||||
// Reserve slot for EEPROM if necessary, avoids having to resize the
|
||||
// components array in the MCU tile entity, which isn't possible currently.
|
||||
if (!components.exists(stack => api.Items.get(stack) == api.Items.get("eeprom"))) {
|
||||
components :+= null
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
nbt.setByte(Settings.namespace + "tier", tier.toByte)
|
||||
nbt.setNewTagList(Settings.namespace + "components", components.toIterable)
|
||||
nbt.setNewTagList(Settings.namespace + "components", components.filter(_ != null).toIterable)
|
||||
nbt.setInteger(Settings.namespace + "storedEnergy", storedEnergy)
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
requiredEnergy = totalRequiredEnergy
|
||||
ServerPacketSender.sendRobotAssembling(this, assembling = true)
|
||||
|
||||
for (slot <- 0 until getSizeInventory) items(slot) = None
|
||||
for (slot <- 0 until getSizeInventory) updateItems(slot, null)
|
||||
markDirty()
|
||||
|
||||
true
|
||||
|
@ -221,7 +221,9 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
|
||||
nbt.setNewCompoundTag("info", info.save)
|
||||
}
|
||||
|
||||
override lazy val items = info.components.map(Option(_))
|
||||
override def items = info.components.map(Option(_))
|
||||
|
||||
override def updateItems(slot: Int, stack: ItemStack): Unit = info.components(slot) = stack
|
||||
|
||||
override def getSizeInventory = info.components.length
|
||||
|
||||
@ -232,4 +234,19 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
|
||||
|
||||
// Nope.
|
||||
override def decrStackSize(slot: Int, amount: Int) = null
|
||||
|
||||
// For hotswapping EEPROMs.
|
||||
def changeEEPROM(newEeprom: ItemStack) = {
|
||||
val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get("eeprom"))
|
||||
if (oldEepromIndex >= 0) {
|
||||
val oldEeprom = info.components(oldEepromIndex)
|
||||
super.setInventorySlotContents(oldEepromIndex, newEeprom)
|
||||
Some(oldEeprom)
|
||||
}
|
||||
else {
|
||||
assert(info.components(getSizeInventory - 1) == null)
|
||||
super.setInventorySlotContents(getSizeInventory - 1, newEeprom)
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import li.cil.oc.api.event.RobotMoveEvent
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.client.gui
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.inventory.InventorySelection
|
||||
@ -402,6 +403,16 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand
|
||||
}
|
||||
}
|
||||
|
||||
// The robot's machine is updated in a tick handler, to avoid delayed tile
|
||||
// entity creation when moving, which would screw over all the things...
|
||||
override protected def updateComputer(): Unit = {}
|
||||
|
||||
override protected def onRunningChanged(): Unit = {
|
||||
super.onRunningChanged()
|
||||
if (isRunning) EventHandler.onRobotStart(this)
|
||||
else EventHandler.onRobotStopped(this)
|
||||
}
|
||||
|
||||
override protected def initialize() {
|
||||
if (isServer) {
|
||||
// Ensure we have a node address, because the proxy needs this to initialize
|
||||
@ -419,6 +430,7 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
else EventHandler.onRobotStopped(this)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -452,6 +464,7 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand
|
||||
// robot's proxy instance.
|
||||
_isOutputEnabled = hasRedstoneCard
|
||||
_isAbstractBusAvailable = hasAbstractBusCard
|
||||
if (isRunning) EventHandler.onRobotStart(this)
|
||||
}
|
||||
|
||||
// Side check for Waila (and other mods that may call this client side).
|
||||
|
@ -98,19 +98,18 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def updateEntity() {
|
||||
override def updateEntity(): Unit = {
|
||||
// If we're not yet in a network we might have just been loaded from disk,
|
||||
// meaning there may be other tile entities that also have not re-joined
|
||||
// the network. We skip the update this round to allow other tile entities
|
||||
// to join the network, too, avoiding issues of missing nodes (e.g. in the
|
||||
// GPU which would otherwise loose track of its screen).
|
||||
if (isServer && isConnected) {
|
||||
// If we're not yet in a network we might have just been loaded from disk,
|
||||
// meaning there may be other tile entities that also have not re-joined
|
||||
// the network. We skip the update this round to allow other tile entities
|
||||
// to join the network, too, avoiding issues of missing nodes (e.g. in the
|
||||
// GPU which would otherwise loose track of its screen).
|
||||
machine.update()
|
||||
updateComputer()
|
||||
|
||||
if (_isRunning != machine.isRunning) {
|
||||
_isRunning = machine.isRunning
|
||||
markDirty()
|
||||
ServerPacketSender.sendComputerState(this)
|
||||
onRunningChanged()
|
||||
}
|
||||
|
||||
updateComponents()
|
||||
@ -119,6 +118,15 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
super.updateEntity()
|
||||
}
|
||||
|
||||
protected def updateComputer(): Unit = {
|
||||
machine.update()
|
||||
}
|
||||
|
||||
protected def onRunningChanged(): Unit = {
|
||||
markDirty()
|
||||
ServerPacketSender.sendComputerState(this)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
|
@ -9,7 +9,9 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait Inventory extends TileEntity with inventory.Inventory {
|
||||
lazy val items = Array.fill[Option[ItemStack]](getSizeInventory)(None)
|
||||
private lazy val inventory = Array.fill[Option[ItemStack]](getSizeInventory)(None)
|
||||
|
||||
def items = inventory
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -2,12 +2,15 @@ package li.cil.oc.common.tileentity.traits
|
||||
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
trait PowerInformation extends TileEntity {
|
||||
private var lastSentRatio = -1.0
|
||||
|
||||
private var ticksUntilSync = 0
|
||||
|
||||
def globalBuffer: Double
|
||||
|
||||
def globalBuffer_=(value: Double): Unit
|
||||
@ -18,12 +21,23 @@ trait PowerInformation extends TileEntity {
|
||||
|
||||
protected def updatePowerInformation() {
|
||||
val ratio = if (globalBufferSize > 0) globalBuffer / globalBufferSize else 0
|
||||
if (lastSentRatio < 0 || math.abs(lastSentRatio - ratio) > (5.0 / 100.0)) {
|
||||
if (shouldSync(ratio) || hasChangedSignificantly(ratio)) {
|
||||
lastSentRatio = ratio
|
||||
ServerPacketSender.sendPowerState(this)
|
||||
}
|
||||
}
|
||||
|
||||
private def hasChangedSignificantly(ratio: Double) = lastSentRatio < 0 || math.abs(lastSentRatio - ratio) > (5.0 / 100.0)
|
||||
|
||||
private def shouldSync(ratio: Double) = {
|
||||
ticksUntilSync -= 1
|
||||
if (ticksUntilSync <= 0) {
|
||||
ticksUntilSync = (100 / Settings.get.tickFrequency).toInt max 1
|
||||
lastSentRatio != ratio
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def readFromNBTForClient(nbt: NBTTagCompound) {
|
||||
super.readFromNBTForClient(nbt)
|
||||
|
@ -220,7 +220,7 @@ object PacketSender {
|
||||
val pb = new SimplePacketBuilder(PacketType.PowerState)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeDouble(t.globalBuffer)
|
||||
pb.writeDouble(math.round(t.globalBuffer))
|
||||
pb.writeDouble(t.globalBufferSize)
|
||||
|
||||
pb.sendToPlayersNearTileEntity(t)
|
||||
|
@ -153,7 +153,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def attackTargetEntityWithCurrentItem(entity: Entity) {
|
||||
callUsingItemInSlot(0, stack => entity match {
|
||||
callUsingItemInSlot(agent.equipmentInventory, 0, stack => entity match {
|
||||
case player: EntityPlayer if !canAttackPlayer(player) => // Avoid player damage.
|
||||
case _ =>
|
||||
val event = new RobotAttackEntityEvent.Pre(agent, entity)
|
||||
@ -173,7 +173,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
false
|
||||
}
|
||||
!cancel && callUsingItemInSlot(0, stack => {
|
||||
!cancel && callUsingItemInSlot(agent.equipmentInventory, 0, stack => {
|
||||
val result = isItemUseAllowed(stack) && (entity.interactFirst(this) || (entity match {
|
||||
case living: EntityLivingBase if getCurrentEquippedItem != null => getCurrentEquippedItem.interactWithEntity(this, living)
|
||||
case _ => false
|
||||
@ -186,7 +186,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
|
||||
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = {
|
||||
callUsingItemInSlot(0, stack => {
|
||||
callUsingItemInSlot(agent.equipmentInventory, 0, stack => {
|
||||
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side, world))) {
|
||||
return ActivationType.None
|
||||
}
|
||||
@ -216,7 +216,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
|
||||
def useEquippedItem(duration: Double) = {
|
||||
callUsingItemInSlot(0, stack => {
|
||||
callUsingItemInSlot(agent.equipmentInventory, 0, stack => {
|
||||
if (!shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_AIR, 0, 0, 0, 0, world))) {
|
||||
tryUseItem(stack, duration)
|
||||
}
|
||||
@ -260,7 +260,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
|
||||
def placeBlock(slot: Int, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||
callUsingItemInSlot(slot, stack => {
|
||||
callUsingItemInSlot(agent.mainInventory, slot, stack => {
|
||||
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side, world))) {
|
||||
return false
|
||||
}
|
||||
@ -270,7 +270,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
|
||||
def clickBlock(x: Int, y: Int, z: Int, side: Int): Double = {
|
||||
callUsingItemInSlot(0, stack => {
|
||||
callUsingItemInSlot(agent.equipmentInventory, 0, stack => {
|
||||
if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, x, y, z, side, world))) {
|
||||
return 0
|
||||
}
|
||||
@ -392,7 +392,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
}
|
||||
}
|
||||
|
||||
private def callUsingItemInSlot[T](slot: Int, f: (ItemStack) => T, repair: Boolean = true) = {
|
||||
private def callUsingItemInSlot[T](inventory: IInventory, slot: Int, f: (ItemStack) => T, repair: Boolean = true) = {
|
||||
val itemsBefore = adjacentItems
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
val oldStack = if (stack != null) stack.copy() else null
|
||||
|
@ -11,6 +11,7 @@ import li.cil.oc.server.agent.Player
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.item.EntityMinecart
|
||||
@ -280,10 +281,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits
|
||||
entity.captureDrops = false
|
||||
for (drop <- entity.capturedDrops) {
|
||||
val stack = drop.getEntityItem
|
||||
player.inventory.addItemStackToInventory(stack)
|
||||
if (stack.stackSize > 0) {
|
||||
player.dropPlayerItemWithRandomChoice(stack, inPlace = false)
|
||||
}
|
||||
InventoryUtils.addToPlayerInventory(stack, player)
|
||||
}
|
||||
entity.capturedDrops.clear()
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -67,10 +68,9 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
|
||||
}
|
||||
}
|
||||
save()
|
||||
val inventory = host.player.inventory
|
||||
inventory.addItemStackToInventory(result)
|
||||
InventoryUtils.addToPlayerInventory(result, host.player)
|
||||
for (stack <- surplus) {
|
||||
inventory.addItemStackToInventory(stack)
|
||||
InventoryUtils.addToPlayerInventory(stack, host.player)
|
||||
}
|
||||
load()
|
||||
}
|
||||
@ -79,7 +79,7 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
|
||||
}
|
||||
|
||||
def load() {
|
||||
val inventory = host.player.inventory
|
||||
val inventory = host.mainInventory()
|
||||
amountPossible = Int.MaxValue
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(toParentSlot(slot))
|
||||
@ -91,7 +91,7 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
|
||||
}
|
||||
|
||||
def save() {
|
||||
val inventory = host.player.inventory
|
||||
val inventory = host.mainInventory()
|
||||
for (slot <- 0 until getSizeInventory) {
|
||||
inventory.setInventorySlotContents(toParentSlot(slot), getStackInSlot(slot))
|
||||
}
|
||||
@ -100,7 +100,7 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
|
||||
private def toParentSlot(slot: Int) = {
|
||||
val col = slot % 3
|
||||
val row = slot / 3
|
||||
row * 4 + col + 4 // first four are always: tool, card, disk, upgrade
|
||||
row * 4 + col
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.util
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.entity.item.EntityMinecartContainer
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.inventory.ISidedInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -233,7 +234,7 @@ object InventoryUtils {
|
||||
/**
|
||||
* Utility method for dumping all inventory contents into the world.
|
||||
*/
|
||||
def dropAllSlots(position: BlockPosition, inventory: IInventory) {
|
||||
def dropAllSlots(position: BlockPosition, inventory: IInventory): Unit = {
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
Option(inventory.getStackInSlot(slot)) match {
|
||||
case Some(stack) if stack.stackSize > 0 =>
|
||||
@ -244,6 +245,23 @@ object InventoryUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try inserting an item stack into a player inventory. If that fails, drop it into the world.
|
||||
*/
|
||||
def addToPlayerInventory(stack: ItemStack, player: EntityPlayer): Unit = {
|
||||
if (stack != null) {
|
||||
if (player.inventory.addItemStackToInventory(stack)) {
|
||||
player.inventory.markDirty()
|
||||
if (player.openContainer != null) {
|
||||
player.openContainer.detectAndSendChanges()
|
||||
}
|
||||
}
|
||||
if (stack.stackSize > 0) {
|
||||
player.dropPlayerItemWithRandomChoice(stack, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for spawning an item stack in the world.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user