mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-27 06:53:08 -04:00
Merge branch 'master-MC1.7.10' into test
# Conflicts: # build.properties
This commit is contained in:
commit
22658251e9
@ -1,7 +1,7 @@
|
||||
minecraft.version=1.7.10
|
||||
forge.version=10.13.4.1614-1.7.10
|
||||
|
||||
oc.version=1.7.4.1
|
||||
oc.version=1.7.5.1
|
||||
|
||||
ae2.version=rv2-beta-26
|
||||
bc.version=7.0.9
|
||||
|
81
changelog.md
81
changelog.md
@ -1,26 +1,69 @@
|
||||
## New Features/Support
|
||||
|
||||
* **Misc: when powering on, drones may fly a bit higher**
|
||||
- will fly a above their starting block to get above nonfull blocks (such as chests)
|
||||
* Misc: more robot names
|
||||
* Misc: robot/drone swing respects harvestability of block vs tool
|
||||
* Fixed: zero sized files (bufferChanges failing to do its job)
|
||||
* Fixed: client crash when using remote terminal out of range
|
||||
* Fixed: inventory controllers now honor specified target slot
|
||||
* Fixed: T1 wireless cards now ignore properly ignore wired messages
|
||||
* Fixed: waila integration by checking for nulls with relay block
|
||||
* Fixed: practical logisitics integration by not passing null for EnumFacing
|
||||
* Fixed: locking items in hotbar when gui is open
|
||||
* Fixed: some container names localized
|
||||
**This will be the last version for Minecraft 1.11.2. Minecraft 1.7.10, 1.10.2, and 1.12.2 will keep receiving updates.**
|
||||
|
||||
* **Added: Barcode reader upgrade!** (AmandaCameron)
|
||||
- An Analyzer can now be installed in a Tablet as an upgrade.
|
||||
- Provides the `barcode_reader` component.
|
||||
- When clicking on a block with a tablet containing this upgrade, the `tablet_use` event will contain information the Analyzer would normally reveal.
|
||||
- This allows getting components' addresses into OC directly by clicking on blocks.
|
||||
* Added: Config option to set max signal queue size (default 256, the same as before).
|
||||
- Signals pushed to the computer when the queue is full are dropped.
|
||||
* Added: Allow different HTTP request methods in `internet.request` (the method to use is now the fourth optional argument).
|
||||
* Added: You can now install Angel Upgrades in drones (Minecraft 1.12 only).
|
||||
* Added: Chargers can now charge items in nearby players' inventories.
|
||||
* Added: Experience Upgrade now shows its level in its tooltip (Minecraft 1.12 only).
|
||||
* Added: Extended item information to Thaumcraft Essentia Jars on Minecraft 1.12 (seebs)
|
||||
* Added: Support for SimpleLogic bundled cables on Minecraft 1.12. (asiekierka)
|
||||
* Added: Re-added Wireless Redstone (ChickenBones Edition) support on Minecraft 1.12.
|
||||
* Misc: Hide bounding box wireframe on screens while not sneaking
|
||||
* Misc: More robot names.
|
||||
* Misc: Updated the chinese translation of the manual. (3TUSK, ZeroAurora, JackyWangMislantiaJnirvana)
|
||||
* Changed: Cleaned up some wording in the config file.
|
||||
* Changed: `gpu.bind` is now faster.
|
||||
* Changed: `computer.pushSignal` now accepts tables of simple key-value pairs, but not nested tables.
|
||||
* Changed: APU tiers now correspond to their CPU tiers.
|
||||
* Changed: Putting unmanaged hard drives into a Raid now forces them into managed mode along with wiping them.
|
||||
* Fixed: Robots being unable to use buckets.
|
||||
* Fixed: Fluid dupe bug that I will _not_ explain to you.
|
||||
* Fixed: Tier 2 wireless network card not receiving wired messages.
|
||||
* Fixed: Return value of `robot.swing` when the block breaks too fast.
|
||||
* Fixed: Server racks not sending messages to mountables quickly enough.
|
||||
* Fixed: Relays not displaying traffic accurately.
|
||||
* Fixed: Relay message relaying issues.
|
||||
* Fixed: `itemDamageRate` config option set to 0 not working. (svitoos)
|
||||
* Fixed: Crash with `hologram.copy`.
|
||||
* Fixed: Geolyzer's `isSunVisible`.
|
||||
* Fixed: Crash with remote terminals.
|
||||
* Fixed: A Robot without inventory deleting the items it drops.
|
||||
* Fixed: `too long without yielding` sometimes not triggering when it should.
|
||||
* Fixed: Crash when blowing up a computer while code is running.
|
||||
* Fixed: Another fluid dupe bug that I will definitely not explain to you either. Stop asking.
|
||||
* Fixed: Available architectures not always being what they should be.
|
||||
* Fixed: Crashes in AE2 integration.
|
||||
* Fixed: The AE2 ME Interface part not having network control.
|
||||
* Fixed: AE2 ME cells not having all intended information on inspection. (wkalinin)
|
||||
* Fixed: Crash with AE2 when power usage is disabled.
|
||||
* Fixed: AE2 interface not being recognized as components when channels are disabled.
|
||||
* Fixed: Some AE2 integration not working on 1.7.10. (wkalinin)
|
||||
* Fixed: Another crash with AE2 when power usage is disabled.
|
||||
* Fixed: Specific AE2 integration being very slow.
|
||||
* Fixed: Crash with IC2 Classic.
|
||||
|
||||
## OpenOS fixes/improvements
|
||||
|
||||
* Fixed: fixed event timing issues when pulling smaller timeouts than a current timer
|
||||
* Added: tty handles '\v' code to move cursor down one line
|
||||
* Misc: some openos cleanup
|
||||
* Misc: more memory savings
|
||||
* Misc: slightly faster boot up times
|
||||
* Fixed: Error related to installing OPPM.
|
||||
* Fixed: OpenOS timers being starved during blocking pulls.
|
||||
* Fixed: `reset` alias to reset the screen resolution to its maximum.
|
||||
* Fixed: Certain TCP connections in Network loot disk
|
||||
* Fixed: Various vt100 fixes
|
||||
* Fixed: Now errors properly on using `print` with bad `__string` metamethods
|
||||
|
||||
## List of contributors
|
||||
payonel, Wilma456
|
||||
Anar Abdullayev, TheCodex6824
|
||||
payonel,
|
||||
AmandaCameron, wkalinin,
|
||||
LizzyTrickster, svitoos,
|
||||
kchanakira, seebs,
|
||||
asiekierka,
|
||||
3TUSK, ZeroAurora,
|
||||
JackyWangMislantiaJnirvana
|
||||
|
@ -47,8 +47,8 @@ item.oc.AbstractBusCard.name=Abstract Bus Card
|
||||
item.oc.Acid.name=Grog
|
||||
item.oc.ALU.name=Arithmetic Logic Unit (ALU)
|
||||
item.oc.Analyzer.name=Analyzer
|
||||
item.oc.APU0.name=Accelerated Processing Unit (APU) (Tier 1)
|
||||
item.oc.APU1.name=Accelerated Processing Unit (APU) (Tier 2)
|
||||
item.oc.APU0.name=Accelerated Processing Unit (APU) (Tier 2)
|
||||
item.oc.APU1.name=Accelerated Processing Unit (APU) (Tier 3)
|
||||
item.oc.APU2.name=Accelerated Processing Unit (APU) (Creative)
|
||||
item.oc.ArrowKeys.name=Arrow Keys
|
||||
item.oc.ButtonGroup.name=Button Group
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- called from /init.lua
|
||||
local raw_loadfile = ...
|
||||
|
||||
_G._OSVERSION = "OpenOS 1.7.4"
|
||||
_G._OSVERSION = "OpenOS 1.7.5"
|
||||
|
||||
-- luacheck: globals component computer unicode _OSVERSION
|
||||
local component = component
|
||||
|
@ -41,6 +41,7 @@ if hookInterval < 1000 then hookInterval = 1000 end
|
||||
|
||||
local deadline = math.huge
|
||||
local hitDeadline = false
|
||||
local tooLongWithoutYielding = setmetatable({}, { __tostring = function() return "too long without yielding" end})
|
||||
local function checkDeadline()
|
||||
if computer.realTime() > deadline then
|
||||
debug.sethook(coroutine.running(), checkDeadline, "", 1)
|
||||
@ -48,9 +49,16 @@ local function checkDeadline()
|
||||
deadline = deadline + 0.5
|
||||
end
|
||||
hitDeadline = true
|
||||
error("too long without yielding", 0)
|
||||
error(tooLongWithoutYielding)
|
||||
end
|
||||
end
|
||||
local function pcallTimeoutCheck(...)
|
||||
local ok, timeout = ...
|
||||
if timeout == tooLongWithoutYielding then
|
||||
return ok, tostring(tooLongWithoutYielding)
|
||||
end
|
||||
return ...
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@ -739,9 +747,7 @@ sandbox = {
|
||||
next = next,
|
||||
pairs = pairs,
|
||||
pcall = function(...)
|
||||
local result = table.pack(pcall(...))
|
||||
checkDeadline()
|
||||
return table.unpack(result, 1, result.n)
|
||||
return pcallTimeoutCheck(pcall(...))
|
||||
end,
|
||||
print = nil, -- in boot/*_base.lua
|
||||
rawequal = rawequal,
|
||||
@ -785,18 +791,23 @@ sandbox = {
|
||||
tonumber = tonumber,
|
||||
tostring = tostring,
|
||||
type = type,
|
||||
_VERSION = _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
|
||||
_VERSION = _VERSION:match("Luaj") and "Luaj" or _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
|
||||
xpcall = function(f, msgh, ...)
|
||||
local handled = false
|
||||
checkArg(2, msgh, "function")
|
||||
local result = table.pack(xpcall(f, function(...)
|
||||
if handled then
|
||||
if (...) == tooLongWithoutYielding then
|
||||
return tooLongWithoutYielding
|
||||
elseif handled then
|
||||
return ...
|
||||
else
|
||||
handled = true
|
||||
return msgh(...)
|
||||
end
|
||||
end, ...))
|
||||
checkDeadline()
|
||||
if result[2] == tooLongWithoutYielding then
|
||||
result = table.pack(result[1], select(2, pcallTimeoutCheck(pcall(msgh, tostring(tooLongWithoutYielding)))))
|
||||
end
|
||||
return table.unpack(result, 1, result.n)
|
||||
end,
|
||||
|
||||
@ -1503,4 +1514,4 @@ end
|
||||
|
||||
-- JNLua converts the coroutine to a string immediately, so we can't get the
|
||||
-- traceback later. Because of that we have to do the error handling here.
|
||||
return pcall(main)
|
||||
return pcallTimeoutCheck(pcall(main))
|
||||
|
@ -88,6 +88,7 @@ Michiyo # Contributor
|
||||
Mycroft Holmes # The Moon Is a Harsh Mistress
|
||||
Pac-Man # Pac-Man
|
||||
Optimus # Transformers. Seperated "Optimus Prime" into two names, as both are quite fitting robot names.
|
||||
Ordis # Warframe
|
||||
P-Body # Portal
|
||||
Pintsize # Questionable Content
|
||||
PixelToast # Contributor
|
||||
|
@ -193,7 +193,7 @@ object EventHandler {
|
||||
if (SideTracker.isServer) e.player match {
|
||||
case _: FakePlayer => // Nope
|
||||
case player: EntityPlayerMP =>
|
||||
if (!LuaStateFactory.isAvailable) {
|
||||
if (!LuaStateFactory.isAvailable && !LuaStateFactory.luajRequested) {
|
||||
player.addChatMessage(Localization.Chat.WarningLuaFallback)
|
||||
}
|
||||
if (Recipes.hadErrors) {
|
||||
|
@ -79,7 +79,7 @@ class Proxy {
|
||||
if (LuaStateFactory.include53) {
|
||||
api.Machine.add(classOf[NativeLua53Architecture])
|
||||
}
|
||||
if (api.Machine.architectures.size == 0) {
|
||||
if (LuaStateFactory.includeLuaJ) {
|
||||
api.Machine.add(classOf[LuaJLuaArchitecture])
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
create()
|
||||
|
||||
val connectors = mutable.Set.empty[Chargeable]
|
||||
val equipment = mutable.Set.empty[ItemStack]
|
||||
|
||||
var chargeSpeed = 0.0
|
||||
|
||||
@ -79,6 +80,14 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
|
||||
override def canUpdate = true
|
||||
|
||||
private def chargeStack(stack: ItemStack, charge: Double): Unit = {
|
||||
if (stack != null && charge > 0) {
|
||||
val offered = charge + node.changeBuffer(-charge)
|
||||
val surplus = ItemCharge.charge(stack, offered)
|
||||
node.changeBuffer(surplus)
|
||||
}
|
||||
}
|
||||
|
||||
override def updateEntity() {
|
||||
super.updateEntity()
|
||||
|
||||
@ -104,11 +113,16 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency
|
||||
canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5
|
||||
if (canCharge) {
|
||||
(0 until getSizeInventory).map(getStackInSlot).foreach(stack => if (stack != null) {
|
||||
val offered = charge + node.changeBuffer(-charge)
|
||||
val surplus = ItemCharge.charge(stack, offered)
|
||||
node.changeBuffer(surplus)
|
||||
})
|
||||
(0 until getSizeInventory).map(getStackInSlot).foreach(chargeStack(_, charge))
|
||||
}
|
||||
}
|
||||
|
||||
// Charging of equipment
|
||||
{
|
||||
val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency
|
||||
canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5
|
||||
if (canCharge) {
|
||||
equipment.foreach(chargeStack(_, charge))
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,17 +233,35 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
}
|
||||
|
||||
val players = world.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect {
|
||||
case player: EntityPlayer if api.Nanomachines.hasController(player) => new PlayerChargeable(player)
|
||||
case player: EntityPlayer => player
|
||||
}
|
||||
|
||||
val chargeablePlayers = players.collect {
|
||||
case player if api.Nanomachines.hasController(player) => new PlayerChargeable(player)
|
||||
}
|
||||
|
||||
// Only update list when we have to, keeps pointless block updates to a minimum.
|
||||
|
||||
val newConnectors = robots ++ drones ++ players
|
||||
val newConnectors = robots ++ drones ++ chargeablePlayers
|
||||
if (connectors.size != newConnectors.length || (connectors.nonEmpty && (connectors -- newConnectors).nonEmpty)) {
|
||||
connectors.clear()
|
||||
connectors ++= newConnectors
|
||||
world.notifyBlocksOfNeighborChange(x, y, z, block)
|
||||
}
|
||||
|
||||
// scan players for chargeable equipment
|
||||
equipment.clear()
|
||||
players.foreach {
|
||||
player => player.inventory.mainInventory.foreach {
|
||||
stack: ItemStack =>
|
||||
if (Option(Driver.driverFor(stack, getClass)) match {
|
||||
case Some(driver) if driver.slot(stack) == Slot.Tablet => true
|
||||
case _ => ItemCharge.canCharge(stack)
|
||||
}) {
|
||||
equipment += stack
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait Chargeable {
|
||||
|
@ -10,6 +10,7 @@ import li.cil.oc.api.Driver
|
||||
import li.cil.oc.api.fs.Label
|
||||
import li.cil.oc.api.network.Analyzable
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.common.item.data.DriveData
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.server.component.FileSystem
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
@ -79,6 +80,14 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl
|
||||
def tryCreateRaid(id: String) {
|
||||
if (items.count(_.isDefined) == items.length && filesystem.fold(true)(fs => fs.node == null || fs.node.address != id)) {
|
||||
filesystem.foreach(fs => if (fs.node != null) fs.node.remove())
|
||||
items.foreach(fs => fs match {
|
||||
case Some(fsStack) =>
|
||||
val drive = new DriveData(fsStack)
|
||||
drive.lockInfo = ""
|
||||
drive.isUnmanaged = false
|
||||
drive.save(fsStack)
|
||||
case _ => // should not happen but is safe to ignore
|
||||
})
|
||||
val fs = api.FileSystem.asManagedEnvironment(
|
||||
api.FileSystem.fromSaveDirectory(id, wipeDisksAndComputeSpace, Settings.get.bufferChanges),
|
||||
label, this, Settings.resourceDomain + ":hdd_access", 6).
|
||||
|
@ -101,7 +101,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
|
||||
case (key: String, value: AnyRef) => (key, value)
|
||||
}
|
||||
result(allCraftables
|
||||
.collect{ case aeCraftItem if matches(convert(aeCraftItem), filter) => new NetworkControl.Craftable(tile, aeCraftItem) }
|
||||
.collect{ case aeCraftItem if filter.isEmpty || matches(convert(aeCraftItem), filter) => new NetworkControl.Craftable(tile, aeCraftItem) }
|
||||
.toArray)
|
||||
}
|
||||
|
||||
|
@ -260,8 +260,10 @@ object PacketSender {
|
||||
val x = (xz >> 8).toByte
|
||||
val z = xz.toByte
|
||||
pb.writeShort(xz)
|
||||
pb.writeInt(t.volume(x + z * t.width))
|
||||
pb.writeInt(t.volume(x + z * t.width + t.width * t.width))
|
||||
val rangeStart: Int = x + z * t.width
|
||||
val rangeFinal: Int = x + z * t.width + t.width * t.width
|
||||
pb.writeInt(t.volume(rangeStart max 0 min t.volume.length - 1))
|
||||
pb.writeInt(t.volume(rangeFinal max 0 min t.volume.length - 1))
|
||||
}
|
||||
|
||||
pb.sendToPlayersNearTileEntity(t)
|
||||
|
@ -187,11 +187,11 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
||||
private def collectDroppedItems(itemsBefore: Iterable[EntityItem]) {
|
||||
val itemsAfter = adjacentItems
|
||||
val itemsDropped = itemsAfter -- itemsBefore
|
||||
for (drop <- itemsDropped) {
|
||||
|
||||
drop.delayBeforeCanPickup = 0
|
||||
drop.onCollideWithPlayer(this)
|
||||
drop.setDead()
|
||||
if (itemsDropped.nonEmpty) {
|
||||
for (drop <- itemsDropped) {
|
||||
drop.delayBeforeCanPickup = 0
|
||||
drop.onCollideWithPlayer(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,11 +288,20 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits
|
||||
entity.captureDrops = true
|
||||
}
|
||||
|
||||
|
||||
protected def endConsumeDrops(player: Player, entity: Entity) {
|
||||
entity.captureDrops = false
|
||||
for (drop <- entity.capturedDrops) {
|
||||
val stack = drop.getEntityItem
|
||||
InventoryUtils.addToPlayerInventory(stack, player)
|
||||
// this inventory size check is a HACK to preserve old behavior that a agent can suck items out
|
||||
// of the capturedDrops. Ideally, we'd only pick up items off the ground. We could clear the
|
||||
// capturedDrops when Player.attackTargetEntityWithCurrentItem() is called
|
||||
// But this felt slightly less hacky, slightly
|
||||
if (player.inventory.getSizeInventory > 0) {
|
||||
for (drop <- entity.capturedDrops) {
|
||||
if (!drop.isDead) {
|
||||
val stack = drop.getEntityItem
|
||||
InventoryUtils.addToPlayerInventory(stack, player, spawnInWorld = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
entity.capturedDrops.clear()
|
||||
}
|
||||
|
@ -22,24 +22,22 @@ import org.apache.commons.lang3.SystemUtils
|
||||
import scala.util.Random
|
||||
|
||||
object LuaStateFactory {
|
||||
def isAvailable = {
|
||||
def isAvailable: Boolean = {
|
||||
// Force initialization of both.
|
||||
val lua52 = Lua52.isAvailable
|
||||
val lua53 = Lua53.isAvailable
|
||||
lua52 || lua53
|
||||
}
|
||||
|
||||
def include52 = {
|
||||
Lua52.isAvailable && !Settings.get.forceLuaJ
|
||||
}
|
||||
def luajRequested: Boolean = Settings.get.forceLuaJ || Settings.get.registerLuaJArchitecture
|
||||
|
||||
def include53 = {
|
||||
Lua53.isAvailable && Settings.get.enableLua53
|
||||
}
|
||||
def includeLuaJ: Boolean = !isAvailable || luajRequested
|
||||
|
||||
def default53 = {
|
||||
include53 && Settings.get.defaultLua53
|
||||
}
|
||||
def include52: Boolean = Lua52.isAvailable && !Settings.get.forceLuaJ
|
||||
|
||||
def include53: Boolean = Lua53.isAvailable && Settings.get.enableLua53 && !Settings.get.forceLuaJ
|
||||
|
||||
def default53: Boolean = include53 && Settings.get.defaultLua53
|
||||
|
||||
def setDefaultArch(stack: ItemStack): ItemStack = {
|
||||
if (default53) {
|
||||
|
@ -156,7 +156,7 @@ object FluidUtils {
|
||||
override def canFill(from: ForgeDirection, fluid: Fluid): Boolean = fluid.canBePlacedInWorld
|
||||
|
||||
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = {
|
||||
if (resource != null && resource.getFluid.canBePlacedInWorld && resource.getFluid.getBlock != null) {
|
||||
if (resource != null && resource.getFluid.canBePlacedInWorld && resource.getFluid.getBlock != null && resource.amount >= 1000) {
|
||||
if (doFill) {
|
||||
val world = position.world.get
|
||||
if (!world.isAirBlock(position) && !world.isAnyLiquid(position.bounds))
|
||||
|
@ -369,7 +369,7 @@ 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 = {
|
||||
def addToPlayerInventory(stack: ItemStack, player: EntityPlayer, spawnInWorld: Boolean = true): Unit = {
|
||||
if (stack != null) {
|
||||
if (player.inventory.addItemStackToInventory(stack)) {
|
||||
player.inventory.markDirty()
|
||||
@ -377,7 +377,7 @@ object InventoryUtils {
|
||||
player.openContainer.detectAndSendChanges()
|
||||
}
|
||||
}
|
||||
if (stack.stackSize > 0) {
|
||||
if (stack.stackSize > 0 && spawnInWorld) {
|
||||
player.dropPlayerItemWithRandomChoice(stack, false)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user