mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-28 23:40:49 -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
4259c8aaf3
14
build.gradle
14
build.gradle
@ -118,27 +118,27 @@ repositories {
|
||||
|
||||
ivy {
|
||||
name 'CoFHLib'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.cofhlib.cf}/[module]-[revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.cofhlib.cf}/[module]-[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'MineFactoryReloaded'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.mfr.cf}/[module]-[revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.mfr.cf}/[module]-[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'ComputerCraft'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.cc.cf}/[module][revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.cc.cf}/[module][revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'EnderIO'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.eio.cf}/[module]-[revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.eio.cf}/[module]-[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'Railcraft'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.rc.cf}/[module]_[revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.rc.cf}/[module]_[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'BloodMagic'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.bloodmagic.cf}/[module]-${config.minecraft.version}-[revision].[ext]"
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.bloodmagic.cf}/[module]-${config.minecraft.version}-[revision].[ext]"
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
provided "api:rotarycraft:${config.rotc.version}"
|
||||
provided "appeng:RotaryCraft:${config.rotc.version}:api"
|
||||
provided "appeng:appliedenergistics2:${config.ae2.version}:dev"
|
||||
provided "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev"
|
||||
provided "codechicken:EnderStorage:${config.minecraft.version}-${config.es.version}:dev"
|
||||
|
@ -1,18 +1,18 @@
|
||||
minecraft.version=1.7.10
|
||||
forge.version=10.13.2.1236
|
||||
forge.version=10.13.2.1291
|
||||
|
||||
oc.version=1.5.4
|
||||
oc.version=1.5.5
|
||||
oc.subversion=
|
||||
|
||||
ae2.version=rv1-stable-1
|
||||
bc.version=6.2.6
|
||||
ae2.version=rv2-beta-22
|
||||
bc.version=6.4.5
|
||||
bloodmagic.cf=2223/203
|
||||
bloodmagic.version=1.3.0a-1
|
||||
cc.cf=2216/236
|
||||
cc.version=1.65
|
||||
ccl.version=1.1.1.104
|
||||
cofhlib.cf=2218/257
|
||||
cofhlib.version=[1.7.10]1.0.0B7-dev-29
|
||||
cofhlib.cf=2230/207
|
||||
cofhlib.version=[1.7.10]1.0.0RC7-127
|
||||
eio.cf=2219/296
|
||||
eio.version=1.7.10-2.2.1.276
|
||||
es.version=1.4.5.24
|
||||
@ -24,14 +24,14 @@ gt.version=5.04.06
|
||||
ic2.version=2.2.654-experimental
|
||||
mekanism.build=5
|
||||
mekanism.version=7.1.2
|
||||
mfr.cf=2213/46
|
||||
mfr.version=[1.7.10]2.8.0RC3-dev-591
|
||||
mfr.cf=2229/626
|
||||
mfr.version=[1.7.10]2.8.0RC8-86
|
||||
nei.version=1.0.3.57
|
||||
projred.version=4.5.8.59
|
||||
rc.cf=2219/321
|
||||
rc.version=1.7.10-9.4.0.0
|
||||
redlogic.version=59.0.3
|
||||
rotc.version=1
|
||||
rotc.version=V5c
|
||||
tmech.version=75.0afb56c
|
||||
re.version=3.0.0.342
|
||||
waila.version=1.5.8a
|
||||
|
@ -1035,6 +1035,12 @@ opencomputers {
|
||||
# this many shapes *per state* (the reasoning being that only one state
|
||||
# will ever be visible at a time).
|
||||
maxPrinterShapes: 24
|
||||
|
||||
# How much of the material used to print a model is refunded when using
|
||||
# the model to refuel a printer. This the value the original material
|
||||
# cost is multiplied with, so 1 is a full refund, 0 disables the
|
||||
# functionality (won't be able to put prints into the material input).
|
||||
printRecycleRate: 0.75
|
||||
}
|
||||
|
||||
# Settings for mod integration (the mod previously known as OpenComponents).
|
||||
|
@ -1,6 +1,11 @@
|
||||
--[[
|
||||
OpenPrograms package manager, browser and downloader, for easy access to many programs
|
||||
Author: Vexatos
|
||||
|
||||
Warning! This file is just an auto-installer for OPPM!
|
||||
DO NOT EVER TRY TO INSTALL A PACKAGE WITH THIS!
|
||||
Once you ran OPPM once, you can remove the floppy disk
|
||||
and run the installed OPPM version just fine.
|
||||
]]
|
||||
local component = require("component")
|
||||
local event = require("event")
|
||||
@ -10,18 +15,22 @@ local serial = require("serialization")
|
||||
local shell = require("shell")
|
||||
local term = require("term")
|
||||
|
||||
local wget = loadfile("/bin/wget.lua")
|
||||
|
||||
local gpu = component.gpu
|
||||
|
||||
if not component.isAvailable("internet") then
|
||||
io.stderr:write("This program requires an internet card to run.")
|
||||
return
|
||||
end
|
||||
local internet = require("internet")
|
||||
local internet
|
||||
local wget
|
||||
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local function getInternet()
|
||||
if not component.isAvailable("internet") then
|
||||
io.stderr:write("This program requires an internet card to run.")
|
||||
return false
|
||||
end
|
||||
internet = require("internet")
|
||||
wget = loadfile("/bin/wget.lua")
|
||||
return true
|
||||
end
|
||||
|
||||
local function printUsage()
|
||||
print("OpenPrograms Package Manager, use this to browse through and download OpenPrograms programs easily")
|
||||
@ -43,9 +52,9 @@ local function getContent(url)
|
||||
if not result then
|
||||
return nil
|
||||
end
|
||||
for chunk in response do
|
||||
sContent = sContent..chunk
|
||||
end
|
||||
for chunk in response do
|
||||
sContent = sContent..chunk
|
||||
end
|
||||
return sContent
|
||||
end
|
||||
|
||||
@ -80,6 +89,9 @@ local function downloadFile(url,path,force)
|
||||
if options.f or force then
|
||||
return wget("-fq",url,path)
|
||||
else
|
||||
if fs.exists(path) then
|
||||
error("file already exists and option -f is not enabled")
|
||||
end
|
||||
return wget("-q",url,path)
|
||||
end
|
||||
end
|
||||
@ -209,6 +221,67 @@ local function printPackages(packs)
|
||||
end
|
||||
end
|
||||
|
||||
local function parseFolders(pack, repo, info)
|
||||
|
||||
local function getFolderTable(repo, namePath, branch)
|
||||
local success, filestring = pcall(getContent,"https://api.github.com/repos/"..repo.."/contents/"..namePath.."?ref="..branch)
|
||||
if not success or filestring:find('"message": "Not Found"') then
|
||||
io.stderr:write("Error while trying to parse folder names in declaration of package "..pack..".\n")
|
||||
if filestring:find('"message": "Not Found"') then
|
||||
io.stderr:write("Folder "..namePath.." does not exist.\n")
|
||||
else
|
||||
io.stderr:write(filestring.."\n")
|
||||
end
|
||||
io.stderr:write("Please contact the author of that package.\n")
|
||||
return nil
|
||||
end
|
||||
return serial.unserialize(filestring:gsub("%[", "{"):gsub("%]", "}"):gsub("(\"[^%s,]-\")%s?:", "[%1] = "), nil)
|
||||
end
|
||||
|
||||
local function nonSpecial(text)
|
||||
return text:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
|
||||
end
|
||||
|
||||
local function unserializeFiles(files, repo, namePath, branch, relPath)
|
||||
if not files then return nil end
|
||||
local tFiles = {}
|
||||
for _,v in pairs(files) do
|
||||
if v["type"] == "file" then
|
||||
local newPath = v["download_url"]:gsub("https?://raw.githubusercontent.com/"..nonSpecial(repo).."(.+)$", "%1"):gsub("/*$",""):gsub("^/*","")
|
||||
tFiles[newPath] = relPath
|
||||
elseif v["type"] == "dir" then
|
||||
local newFiles = unserializeFiles(getFolderTable(repo, relPath.."/"..v["name"], branch), repo, branch, fs.concat(relPath, v["name"]))
|
||||
for p,q in pairs(newFiles) do
|
||||
tFiles[p] = q
|
||||
end
|
||||
end
|
||||
end
|
||||
return tFiles
|
||||
end
|
||||
|
||||
local newInfo = info
|
||||
for i,j in pairs(info.files) do
|
||||
if string.find(i,"^:") then
|
||||
local iPath = i:gsub("^:","")
|
||||
local branch = string.gsub(iPath,"^(.-)/.+","%1"):gsub("/*$",""):gsub("^/*","")
|
||||
local namePath = string.gsub(iPath,".-(/.+)$","%1"):gsub("/*$",""):gsub("^/*","")
|
||||
local absolutePath = j:find("^//")
|
||||
|
||||
local files = unserializeFiles(getFolderTable(repo, namePath, branch), repo, namePath, branch, j:gsub("^//","/"))
|
||||
if not files then return nil end
|
||||
for p,q in pairs(files) do
|
||||
if absolutePath then
|
||||
newInfo.files[p] = "/"..q
|
||||
else
|
||||
newInfo.files[p] = q
|
||||
end
|
||||
end
|
||||
newInfo.files[i] = nil
|
||||
end
|
||||
end
|
||||
return newInfo
|
||||
end
|
||||
|
||||
local function getInformation(pack)
|
||||
local success, repos = pcall(getRepos)
|
||||
if not success or repos==-1 then
|
||||
@ -223,7 +296,7 @@ local function getInformation(pack)
|
||||
elseif type(lPacks) == "table" then
|
||||
for k in pairs(lPacks) do
|
||||
if k==pack then
|
||||
return lPacks[k],j.repo
|
||||
return parseFolders(pack, j.repo, lPacks[k]),j.repo
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -234,7 +307,7 @@ local function getInformation(pack)
|
||||
for i,j in pairs(lRepos.repos) do
|
||||
for k in pairs(j) do
|
||||
if k==pack then
|
||||
return j[k],i
|
||||
return parseFolders(pack, i, j[k]),i
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -271,14 +344,17 @@ local function provideInfo(pack)
|
||||
print("Note: "..info.note)
|
||||
done = true
|
||||
end
|
||||
if info.files then
|
||||
print("Number of files: "..tostring(#info.files))
|
||||
done = true
|
||||
end
|
||||
if not done then
|
||||
print("No information provided.")
|
||||
end
|
||||
end
|
||||
|
||||
local tPacks = readFromFile(1)
|
||||
|
||||
local function installPackage(pack,path,update)
|
||||
local tPacks = readFromFile(1)
|
||||
update = update or false
|
||||
if not pack then
|
||||
printUsage()
|
||||
@ -309,8 +385,12 @@ local function installPackage(pack,path,update)
|
||||
if update then
|
||||
print("Updating package "..pack)
|
||||
path = nil
|
||||
if not tPacks[pack] then
|
||||
io.stderr:write("error while checking update path")
|
||||
return
|
||||
end
|
||||
for i,j in pairs(info.files) do
|
||||
if tPacks[pack] then
|
||||
if not string.find(j,"^//") then
|
||||
for k,v in pairs(tPacks[pack]) do
|
||||
if k==i then
|
||||
path = string.gsub(fs.path(v),j.."/?$","/")
|
||||
@ -320,9 +400,6 @@ local function installPackage(pack,path,update)
|
||||
if path then
|
||||
break
|
||||
end
|
||||
else
|
||||
io.stderr:write("error while checking update path")
|
||||
return
|
||||
end
|
||||
end
|
||||
path = shell.resolve(string.gsub(path,"^/?","/"),nil)
|
||||
@ -381,7 +458,8 @@ local function installPackage(pack,path,update)
|
||||
if success and response then
|
||||
tPacks[pack][i] = nPath
|
||||
else
|
||||
term.write("Error while installing files for package '"..pack.."'. Reverting installation... ")
|
||||
response = response or "no error message"
|
||||
term.write("Error while installing files for package '"..pack.."': "..response..". Reverting installation... ")
|
||||
fs.remove(nPath)
|
||||
for o,p in pairs(tPacks[pack]) do
|
||||
fs.remove(p)
|
||||
@ -405,7 +483,8 @@ local function installPackage(pack,path,update)
|
||||
if success and response then
|
||||
tPacks[pack][i] = nPath
|
||||
else
|
||||
term.write("Error while installing dependency package '"..i.."'. Reverting installation... ")
|
||||
response = response or "no error message"
|
||||
term.write("Error while installing files for package '"..pack.."': "..response..". Reverting installation... ")
|
||||
fs.remove(nPath)
|
||||
for o,p in pairs(tPacks[pack]) do
|
||||
fs.remove(p)
|
||||
@ -429,11 +508,6 @@ local function installPackage(pack,path,update)
|
||||
end
|
||||
|
||||
local function uninstallPackage(pack)
|
||||
local info,repo = getInformation(pack)
|
||||
if not info then
|
||||
print("Package does not exist")
|
||||
return
|
||||
end
|
||||
local tFiles = readFromFile(1)
|
||||
if not tFiles then
|
||||
io.stderr:write("Error while trying to read package names")
|
||||
@ -443,7 +517,8 @@ local function uninstallPackage(pack)
|
||||
end
|
||||
if not tFiles[pack] then
|
||||
print("Package has not been installed.")
|
||||
print("If it has, you have to remove it manually.")
|
||||
print("If it has, the package could not be identified.")
|
||||
print("In this case you have to remove it manually.")
|
||||
return
|
||||
end
|
||||
term.write("Removing package files...")
|
||||
@ -482,13 +557,17 @@ end
|
||||
|
||||
if options.iKnowWhatIAmDoing then
|
||||
if args[1] == "list" then
|
||||
if not getInternet() then return end
|
||||
local packs = listPackages(args[2])
|
||||
printPackages(packs)
|
||||
elseif args[1] == "info" then
|
||||
if not getInternet() then return end
|
||||
provideInfo(args[2])
|
||||
elseif args[1] == "install" then
|
||||
if not getInternet() then return end
|
||||
installPackage(args[2],args[3],false)
|
||||
elseif args[1] == "update" then
|
||||
if not getInternet() then return end
|
||||
updatePackage(args[2])
|
||||
elseif args[1] == "uninstall" then
|
||||
uninstallPackage(args[2])
|
||||
|
@ -21,5 +21,6 @@ else
|
||||
io.write(line)
|
||||
end
|
||||
until not line
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -908,7 +908,7 @@ wrappedUserdataMeta = {
|
||||
local wrappedUserdata = setmetatable({}, wrappedUserdataMeta)
|
||||
|
||||
local function processResult(result)
|
||||
wrapUserdata(result) -- needed for metamethods.
|
||||
result = wrapUserdata(result) -- needed for metamethods.
|
||||
if not result[1] then -- error that should be re-thrown.
|
||||
error(result[2], 0)
|
||||
else -- success or already processed error.
|
||||
@ -920,8 +920,9 @@ local function invoke(target, direct, ...)
|
||||
local result
|
||||
if direct then
|
||||
local args = table.pack(...) -- for unwrapping
|
||||
unwrapUserdata(args)
|
||||
args = unwrapUserdata(args)
|
||||
result = table.pack(target.invoke(table.unpack(args, 1, args.n)))
|
||||
args = nil -- clear upvalue, avoids trying to persist it
|
||||
if result.n == 0 then -- limit for direct calls reached
|
||||
result = nil
|
||||
end
|
||||
@ -930,9 +931,10 @@ local function invoke(target, direct, ...)
|
||||
if not result then
|
||||
local args = table.pack(...) -- for access in closure
|
||||
result = select(1, coroutine.yield(function()
|
||||
unwrapUserdata(args)
|
||||
args = unwrapUserdata(args)
|
||||
local result = table.pack(target.invoke(table.unpack(args, 1, args.n)))
|
||||
wrapUserdata(result)
|
||||
args = nil -- clear upvalue, avoids trying to persist it
|
||||
result = wrapUserdata(result)
|
||||
return result
|
||||
end))
|
||||
end
|
||||
@ -941,8 +943,9 @@ end
|
||||
|
||||
local function udinvoke(f, data, ...)
|
||||
local args = table.pack(...)
|
||||
unwrapUserdata(args)
|
||||
args = unwrapUserdata(args)
|
||||
local result = table.pack(f(data, table.unpack(args)))
|
||||
args = nil -- clear upvalue, avoids trying to persist it
|
||||
return processResult(result)
|
||||
end
|
||||
|
||||
@ -1035,7 +1038,7 @@ function wrapUserdata(values)
|
||||
end
|
||||
return value
|
||||
end
|
||||
wrapRecursively(values)
|
||||
return wrapRecursively(values)
|
||||
end
|
||||
|
||||
function unwrapUserdata(values)
|
||||
@ -1054,7 +1057,7 @@ function unwrapUserdata(values)
|
||||
end
|
||||
return value
|
||||
end
|
||||
unwrapRecursively(values)
|
||||
return unwrapRecursively(values)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -1343,13 +1346,14 @@ local function main()
|
||||
|
||||
debug.sethook(co, checkDeadline, "", hookInterval)
|
||||
local result = table.pack(coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
args = nil -- clear upvalue, avoids trying to persist it
|
||||
if not result[1] then
|
||||
error(tostring(result[2]), 0)
|
||||
elseif coroutine.status(co) == "dead" then
|
||||
error("computer halted", 0)
|
||||
else
|
||||
args = table.pack(coroutine.yield(result[2])) -- system yielded value
|
||||
wrapUserdata(args)
|
||||
args = wrapUserdata(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -294,6 +294,7 @@ class Settings(val config: Config) {
|
||||
val assemblerBlacklist = config.getStringList("misc.assemblerBlacklist")
|
||||
val threadPriority = config.getInt("misc.threadPriority")
|
||||
val maxPrintComplexity = config.getInt("misc.maxPrinterShapes")
|
||||
val printRecycleRate = config.getDouble("misc.printRecycleRate")
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// integration
|
||||
|
@ -141,7 +141,8 @@ object BlockRenderer extends ISimpleBlockRenderingHandler {
|
||||
}
|
||||
|
||||
// The texture flip this works around only seems to occur for blocks with custom block renderers?
|
||||
def patchedRenderer(renderer: RenderBlocks, block: Block) = if (block.isInstanceOf[Hologram] || block.isInstanceOf[Printer]) {
|
||||
def patchedRenderer(renderer: RenderBlocks, block: Block) =
|
||||
if (block.isInstanceOf[Hologram] || block.isInstanceOf[Printer] || block.isInstanceOf[Print]) {
|
||||
PatchedRenderBlocks.blockAccess = renderer.blockAccess
|
||||
PatchedRenderBlocks.overrideBlockTexture = renderer.overrideBlockTexture
|
||||
PatchedRenderBlocks.flipTexture = renderer.flipTexture
|
||||
|
@ -258,24 +258,24 @@ object ItemRenderer extends IItemRenderer {
|
||||
|
||||
// Front.
|
||||
GL11.glNormal3f(0, 0, 1)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(bounds.minY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.minY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(bounds.minY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.minY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(bounds.maxY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.maxY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(bounds.maxY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.maxY, bounds.maxZ)
|
||||
|
||||
// Back.
|
||||
GL11.glNormal3f(0, 0, -1)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(bounds.minY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.minY, bounds.minZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(bounds.minY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.minY, bounds.minZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(bounds.maxY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minX * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.maxY, bounds.minZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(bounds.maxY * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxX * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.maxY, bounds.minZ)
|
||||
|
||||
// Top.
|
||||
@ -302,24 +302,24 @@ object ItemRenderer extends IItemRenderer {
|
||||
|
||||
// Left.
|
||||
GL11.glNormal3f(1, 0, 0)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxY * 16), texture.getInterpolatedV(bounds.maxZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxZ * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.maxY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minY * 16), texture.getInterpolatedV(bounds.maxZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxZ * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.minY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minY * 16), texture.getInterpolatedV(bounds.minZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minZ * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.minY, bounds.minZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxY * 16), texture.getInterpolatedV(bounds.minZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minZ * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.maxX, bounds.maxY, bounds.minZ)
|
||||
|
||||
// Right.
|
||||
GL11.glNormal3f(-1, 0, 0)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minY * 16), texture.getInterpolatedV(bounds.maxZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxZ * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.minY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxY * 16), texture.getInterpolatedV(bounds.maxZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxZ * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.maxY, bounds.maxZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.maxY * 16), texture.getInterpolatedV(bounds.minZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minZ * 16), texture.getInterpolatedV(16 - bounds.maxY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.maxY, bounds.minZ)
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minY * 16), texture.getInterpolatedV(bounds.minZ * 16))
|
||||
GL11.glTexCoord2f(texture.getInterpolatedU(bounds.minZ * 16), texture.getInterpolatedV(16 - bounds.minY * 16))
|
||||
GL11.glVertex3d(bounds.minX, bounds.minY, bounds.minZ)
|
||||
|
||||
GL11.glEnd()
|
||||
|
@ -22,6 +22,7 @@ import li.cil.oc.common.tileentity.traits.power
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util
|
||||
import li.cil.oc.server.component.Keyboard
|
||||
import li.cil.oc.server.machine.Machine
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util._
|
||||
import net.minecraft.client.Minecraft
|
||||
@ -49,12 +50,16 @@ object EventHandler {
|
||||
|
||||
private val keyboards = java.util.Collections.newSetFromMap[Keyboard](new java.util.WeakHashMap[Keyboard, java.lang.Boolean])
|
||||
|
||||
private val machines = mutable.Set.empty[Machine]
|
||||
|
||||
def onRobotStart(robot: Robot): Unit = runningRobots += robot
|
||||
|
||||
def onRobotStopped(robot: Robot): Unit = runningRobots -= robot
|
||||
|
||||
def addKeyboard(keyboard: Keyboard): Unit = keyboards += keyboard
|
||||
|
||||
def scheduleClose(machine: Machine) = machines += machine
|
||||
|
||||
def schedule(tileEntity: TileEntity) {
|
||||
if (SideTracker.isServer) pending.synchronized {
|
||||
pending += (() => Network.joinOrCreateNetwork(tileEntity))
|
||||
@ -130,6 +135,10 @@ object EventHandler {
|
||||
else if (robot.world != null) robot.machine.update()
|
||||
})
|
||||
runningRobots --= invalid
|
||||
|
||||
val closed = mutable.ArrayBuffer.empty[Machine]
|
||||
machines.foreach(machine => if (machine.tryClose()) closed += machine)
|
||||
machines --= closed
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@ -243,7 +252,7 @@ object EventHandler {
|
||||
|
||||
didRecraft = recraft(e, tablet, stack => {
|
||||
// Restore EEPROM currently used in tablet.
|
||||
new TabletData(stack).items.collect { case Some(item) => item}.find(api.Items.get(_) == eeprom)
|
||||
new TabletData(stack).items.collect { case Some(item) => item }.find(api.Items.get(_) == eeprom)
|
||||
}) || didRecraft
|
||||
|
||||
// Presents?
|
||||
|
@ -16,6 +16,7 @@ import net.minecraft.util.IChatComponent
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.language.existentials
|
||||
|
||||
object AssemblerTemplates {
|
||||
val NoSlot = new Slot(Slot.None, Tier.None, None, None)
|
||||
|
@ -188,10 +188,36 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def canUpdate = isServer
|
||||
def computeCosts(data: PrintData) = {
|
||||
val totalVolume = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.volume) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.volume)
|
||||
val totalSurface = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.surface) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.surface)
|
||||
|
||||
if (totalVolume > 0) {
|
||||
val materialRequired = (totalVolume / 2) max 1
|
||||
val inkRequired = (totalSurface / 6) max 1
|
||||
|
||||
Option((materialRequired, inkRequired))
|
||||
}
|
||||
else None
|
||||
}
|
||||
|
||||
def materialValue(stack: ItemStack) = {
|
||||
if (api.Items.get(stack) == api.Items.get("chamelium"))
|
||||
materialPerItem
|
||||
else if (api.Items.get(stack) == api.Items.get("print")) {
|
||||
val data = new PrintData(stack)
|
||||
computeCosts(data) match {
|
||||
case Some((materialRequired, inkRequired)) => (materialRequired * Settings.get.printRecycleRate).toInt
|
||||
case _ => 0
|
||||
}
|
||||
}
|
||||
else 0
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def canUpdate = isServer
|
||||
|
||||
override def updateEntity() {
|
||||
super.updateEntity()
|
||||
|
||||
@ -202,28 +228,22 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
}
|
||||
|
||||
if (isActive && output.isEmpty && canMergeOutput) {
|
||||
val totalVolume = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.volume) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.volume)
|
||||
val totalSurface = data.stateOn.foldLeft(0)((acc, shape) => acc + shape.bounds.surface) + data.stateOff.foldLeft(0)((acc, shape) => acc + shape.bounds.surface)
|
||||
computeCosts(data) match {
|
||||
case Some((materialRequired, inkRequired)) =>
|
||||
totalRequiredEnergy = Settings.get.printCost
|
||||
requiredEnergy = totalRequiredEnergy
|
||||
|
||||
if (totalVolume == 0) {
|
||||
isActive = false
|
||||
data = new PrintData()
|
||||
}
|
||||
else {
|
||||
val materialRequired = (totalVolume / 2) max 1
|
||||
val inkRequired = (totalSurface / 6) max 1
|
||||
|
||||
totalRequiredEnergy = Settings.get.printCost
|
||||
requiredEnergy = totalRequiredEnergy
|
||||
|
||||
if (amountMaterial >= materialRequired && amountInk >= inkRequired) {
|
||||
amountMaterial -= materialRequired
|
||||
amountInk -= inkRequired
|
||||
limit -= 1
|
||||
output = Option(data.createItemStack())
|
||||
if (limit < 1) isActive = false
|
||||
ServerPacketSender.sendPrinting(this, printing = true)
|
||||
}
|
||||
if (amountMaterial >= materialRequired && amountInk >= inkRequired) {
|
||||
amountMaterial -= materialRequired
|
||||
amountInk -= inkRequired
|
||||
limit -= 1
|
||||
output = Option(data.createItemStack())
|
||||
if (limit < 1) isActive = false
|
||||
ServerPacketSender.sendPrinting(this, printing = true)
|
||||
}
|
||||
case _ =>
|
||||
isActive = false
|
||||
data = new PrintData()
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,10 +269,11 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
ServerPacketSender.sendPrinting(this, have > 0.5 && output.isDefined)
|
||||
}
|
||||
|
||||
if (maxAmountMaterial - amountMaterial >= materialPerItem) {
|
||||
val inputValue = materialValue(getStackInSlot(slotMaterial))
|
||||
if (inputValue > 0 && maxAmountMaterial - amountMaterial >= inputValue) {
|
||||
val material = decrStackSize(slotMaterial, 1)
|
||||
if (material != null) {
|
||||
amountMaterial += materialPerItem
|
||||
amountMaterial += inputValue
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,9 +331,9 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
override def getInventoryStackLimit = 64
|
||||
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
||||
if (slot == 0)
|
||||
api.Items.get(stack) == api.Items.get("chamelium")
|
||||
else if (slot == 1)
|
||||
if (slot == slotMaterial)
|
||||
materialValue(stack) > 0
|
||||
else if (slot == slotInk)
|
||||
api.Items.get(stack) == api.Items.get("inkCartridge")
|
||||
else false
|
||||
|
||||
|
@ -127,6 +127,13 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
ServerPacketSender.sendComputerState(this)
|
||||
}
|
||||
|
||||
override def dispose(): Unit = {
|
||||
super.dispose()
|
||||
if (machine != null && !this.isInstanceOf[RobotProxy]) {
|
||||
machine.stop()
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
|
@ -3,7 +3,7 @@ package li.cil.oc.integration;
|
||||
public interface Mod {
|
||||
String id();
|
||||
|
||||
boolean isAvailable();
|
||||
boolean isModAvailable();
|
||||
|
||||
boolean providesPower();
|
||||
}
|
||||
|
@ -56,10 +56,12 @@ object Mods {
|
||||
val StargateTech2 = new ModBase {
|
||||
def id = IDs.StargateTech2
|
||||
|
||||
protected override lazy val isModAvailable = Loader.isModLoaded(IDs.StargateTech2) && {
|
||||
private lazy val isModAvailable_ = Loader.isModLoaded(IDs.StargateTech2) && {
|
||||
val mod = Loader.instance.getIndexedModList.get(IDs.StargateTech2)
|
||||
mod.getVersion.startsWith("0.7.")
|
||||
}
|
||||
|
||||
override def isModAvailable: Boolean = isModAvailable_
|
||||
}
|
||||
val Thaumcraft = new SimpleMod(IDs.Thaumcraft)
|
||||
val ThermalExpansion = new SimpleMod(IDs.ThermalExpansion, providesPower = true)
|
||||
@ -121,7 +123,7 @@ object Mods {
|
||||
private def tryInit(mod: ModProxy) {
|
||||
val isBlacklisted = Settings.get.modBlacklist.contains(mod.getMod.id)
|
||||
val alwaysEnabled = mod.getMod == null || mod.getMod == Mods.Minecraft
|
||||
if (!isBlacklisted && (alwaysEnabled || mod.getMod.isAvailable) && handlers.add(mod)) {
|
||||
if (!isBlacklisted && (alwaysEnabled || mod.getMod.isModAvailable) && handlers.add(mod)) {
|
||||
li.cil.oc.OpenComputers.log.info(s"Initializing mod integration for '${mod.getMod.id}'.")
|
||||
try mod.initialize() catch {
|
||||
case e: Throwable =>
|
||||
@ -188,7 +190,7 @@ object Mods {
|
||||
|
||||
protected lazy val isPowerModEnabled = !providesPower || (!Settings.get.pureIgnorePower && !Settings.get.powerModBlacklist.contains(id))
|
||||
|
||||
protected def isModAvailable: Boolean
|
||||
def isModAvailable: Boolean
|
||||
|
||||
def id: String
|
||||
|
||||
@ -199,21 +201,29 @@ object Mods {
|
||||
// This is called from the class transformer when injecting an interface of
|
||||
// this power type fails, to avoid class not found / class cast exceptions.
|
||||
def disablePower() = powerDisabled = true
|
||||
|
||||
def container = Option(Loader.instance.getIndexedModList.get(id))
|
||||
|
||||
def version = container.map(_.getProcessedVersion)
|
||||
}
|
||||
|
||||
class SimpleMod(val id: String, override val providesPower: Boolean = false, version: String = "") extends ModBase {
|
||||
override protected lazy val isModAvailable = {
|
||||
private lazy val isModAvailable_ = {
|
||||
val version = VersionParser.parseVersionReference(id + this.version)
|
||||
if (Loader.isModLoaded(version.getLabel))
|
||||
version.containsVersion(Loader.instance.getIndexedModList.get(version.getLabel).getProcessedVersion)
|
||||
else ModAPIManager.INSTANCE.hasAPI(version.getLabel)
|
||||
}
|
||||
|
||||
def isModAvailable = isModAvailable_
|
||||
}
|
||||
|
||||
class ClassBasedMod(val id: String, val classNames: String*)(override val providesPower: Boolean = false) extends ModBase {
|
||||
override protected lazy val isModAvailable = classNames.forall(className => try Class.forName(className) != null catch {
|
||||
private lazy val isModAvailable_ = classNames.forall(className => try Class.forName(className) != null catch {
|
||||
case _: Throwable => false
|
||||
})
|
||||
|
||||
def isModAvailable = isModAvailable_
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,12 +7,12 @@ import appeng.api.networking.crafting.ICraftingRequester
|
||||
import appeng.api.networking.security.IActionHost
|
||||
import appeng.api.networking.security.MachineSource
|
||||
import appeng.api.storage.data.IAEItemStack
|
||||
import appeng.core.Api
|
||||
import appeng.me.helpers.IGridProxyable
|
||||
import appeng.tile.misc.TileInterface
|
||||
import appeng.tile.networking.TileController
|
||||
import appeng.util.item.AEItemStack
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import cpw.mods.fml.common.Loader
|
||||
import cpw.mods.fml.common.versioning.VersionRange
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api.driver.EnvironmentAware
|
||||
import li.cil.oc.api.driver.NamedBlock
|
||||
@ -24,9 +24,11 @@ import li.cil.oc.api.prefab.AbstractValue
|
||||
import li.cil.oc.api.prefab.DriverTileEntity
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.integration.ManagedTileEntityEnvironment
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ResultWrapper._
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
@ -40,14 +42,24 @@ import scala.collection.convert.WrapAsScala._
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import scala.language.existentials
|
||||
|
||||
object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
private type AETile = TileEntity with IGridProxyable with IActionHost
|
||||
|
||||
def getTileEntityClass = {
|
||||
if (AEApi.instance != null && AEApi.instance.blocks != null) {
|
||||
val versionsWithNewItemDefinitionAPI = VersionRange.createFromVersionSpec("[rv2-beta-20,)")
|
||||
|
||||
def getTileEntityClass: Class[_] = {
|
||||
if (versionsWithNewItemDefinitionAPI.containsVersion(Loader.instance.getIndexedModList.get(Mods.AppliedEnergistics2.id).getProcessedVersion)) {
|
||||
if (AEApi.instance.definitions.blocks.controller.maybeStack(0).isPresent)
|
||||
AEApi.instance.definitions.blocks.controller.maybeEntity.orNull
|
||||
else
|
||||
AEApi.instance.definitions.blocks.iface.maybeEntity.orNull
|
||||
}
|
||||
else if (AEApi.instance != null && AEApi.instance.blocks != null) {
|
||||
if (AEApi.instance.blocks.blockController != null && AEApi.instance.blocks.blockController.item != null)
|
||||
classOf[TileController]
|
||||
// Not classOf[TileController] because that derps the compiler when it tries to resolve the class (says can't find API classes from RotaryCraft).
|
||||
Class.forName("appeng.tile.networking.TileController")
|
||||
else
|
||||
classOf[TileInterface]
|
||||
}
|
||||
@ -78,10 +90,13 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
"coprocessors" -> cpu.getCoProcessors,
|
||||
"busy" -> cpu.isBusy)))
|
||||
|
||||
@Callback(doc = "function():table -- Get a list of known item recipes. These can be used to issue crafting requests.")
|
||||
@Callback(doc = "function([filter:table]):table -- Get a list of known item recipes. These can be used to issue crafting requests.")
|
||||
def getCraftables(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val filter = args.optTable(0, Map.empty[AnyRef, AnyRef]).collect {
|
||||
case (key: String, value: AnyRef) => (key, value)
|
||||
}
|
||||
result(tileEntity.getProxy.getStorage.getItemInventory.getStorageList.
|
||||
filter(_.isCraftable).map(stack => {
|
||||
filter(_.isCraftable).filter(stack => matches(stack, filter)).map(stack => {
|
||||
val patterns = tileEntity.getProxy.getCrafting.getCraftingFor(stack, null, 0, tileEntity.getWorldObj)
|
||||
val result = patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(stack))) match {
|
||||
case Some(pattern) => pattern.getOutputs.find(_.isSameType(stack)).get
|
||||
@ -91,9 +106,13 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
}).toArray)
|
||||
}
|
||||
|
||||
@Callback(doc = "function():table -- Get a list of the stored items in the network.")
|
||||
def getItemsInNetwork(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(tileEntity.getProxy.getStorage.getItemInventory.getStorageList.map(_.getItemStack).toArray)
|
||||
@Callback(doc = "function([filter:table]):table -- Get a list of the stored items in the network.")
|
||||
def getItemsInNetwork(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val filter = args.optTable(0, Map.empty[AnyRef, AnyRef]).collect {
|
||||
case (key: String, value: AnyRef) => (key, value)
|
||||
}
|
||||
result(tileEntity.getProxy.getStorage.getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).toArray)
|
||||
}
|
||||
|
||||
@Callback(doc = "function():table -- Get a list of the stored fluids in the network.")
|
||||
def getFluidsInNetwork(context: Context, args: Arguments): Array[AnyRef] =
|
||||
@ -118,6 +137,17 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
@Callback(doc = "function():number -- Get the stored power in the network. ")
|
||||
def getStoredPower(context: Context, args: Arguments): Array[AnyRef] =
|
||||
result(tileEntity.getProxy.getEnergy.getStoredPower)
|
||||
|
||||
private def matches(stack: IAEItemStack, filter: scala.collection.mutable.Map[String, AnyRef]) = {
|
||||
stack != null &&
|
||||
filter.get("damage").forall(_.equals(stack.getItemDamage.toDouble)) &&
|
||||
filter.get("maxDamage").forall(_.equals(stack.getItemStack.getMaxDamage.toDouble)) &&
|
||||
filter.get("size").forall(_.equals(stack.getStackSize.toDouble)) &&
|
||||
filter.get("maxSize").forall(_.equals(stack.getItemStack.getMaxStackSize.toDouble)) &&
|
||||
filter.get("hasTag").forall(_.equals(stack.hasTagCompound)) &&
|
||||
filter.get("name").forall(_.equals(Item.itemRegistry.getNameForObject(stack.getItem))) &&
|
||||
filter.get("label").forall(_.equals(stack.getItemStack.getDisplayName))
|
||||
}
|
||||
}
|
||||
|
||||
class Craftable(var controller: AETile, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester {
|
||||
@ -210,7 +240,7 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
})
|
||||
}
|
||||
links ++= nbt.getTagList("links", NBT.TAG_COMPOUND).map(
|
||||
(nbt: NBTTagCompound) => Api.instance.storage.loadCraftingLink(nbt, this))
|
||||
(nbt: NBTTagCompound) => AEApi.instance.storage.loadCraftingLink(nbt, this))
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
|
@ -0,0 +1,52 @@
|
||||
package li.cil.oc.integration.cofh.energy;
|
||||
|
||||
import cofh.api.energy.IEnergyProvider;
|
||||
import cofh.api.energy.IEnergyReceiver;
|
||||
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.ManagedEnvironment;
|
||||
import li.cil.oc.api.prefab.DriverTileEntity;
|
||||
import li.cil.oc.integration.ManagedTileEntityEnvironment;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public final class DriverEnergyProvider extends DriverTileEntity {
|
||||
@Override
|
||||
public Class<?> getTileEntityClass() {
|
||||
return IEnergyProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
|
||||
return new Environment((IEnergyProvider) world.getTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<IEnergyProvider> {
|
||||
public Environment(final IEnergyProvider tileEntity) {
|
||||
super(tileEntity, "energy_handler");
|
||||
}
|
||||
|
||||
@Callback(doc = "function([direction:number=6]):number -- Returns the amount of stored energy for the given side.")
|
||||
public Object[] getEnergyStored(final Context context, final Arguments args) {
|
||||
final ForgeDirection side = args.count() > 0 ? ForgeDirection.getOrientation(args.checkInteger(0)) : ForgeDirection.UNKNOWN;
|
||||
return new Object[]{tileEntity.getEnergyStored(side)};
|
||||
}
|
||||
|
||||
@Callback(doc = "function([direction:number=6]):number -- Returns the maximum amount of stored energy for the given side.")
|
||||
public Object[] getMaxEnergyStored(final Context context, final Arguments args) {
|
||||
final ForgeDirection side = args.count() > 0 ? ForgeDirection.getOrientation(args.checkInteger(0)) : ForgeDirection.UNKNOWN;
|
||||
return new Object[]{tileEntity.getMaxEnergyStored(side)};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Returns whether this component can provide energy.")
|
||||
public Object[] isEnergyProvider(final Context context, final Arguments args) {
|
||||
return new Object[]{true};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Returns whether this component can receive energy.")
|
||||
public Object[] isEnergyReceiver(final Context context, final Arguments args) {
|
||||
return new Object[]{tileEntity instanceof IEnergyReceiver};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package li.cil.oc.integration.cofh.energy;
|
||||
|
||||
import cofh.api.energy.IEnergyProvider;
|
||||
import cofh.api.energy.IEnergyReceiver;
|
||||
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.ManagedEnvironment;
|
||||
import li.cil.oc.api.prefab.DriverTileEntity;
|
||||
import li.cil.oc.integration.ManagedTileEntityEnvironment;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public final class DriverEnergyReceiver extends DriverTileEntity {
|
||||
@Override
|
||||
public Class<?> getTileEntityClass() {
|
||||
return IEnergyReceiver.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean worksWith(World world, int x, int y, int z) {
|
||||
return super.worksWith(world, x, y, z) && !(world.getTileEntity(x, y, z) instanceof IEnergyProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
|
||||
return new Environment((IEnergyReceiver) world.getTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<IEnergyReceiver> {
|
||||
public Environment(final IEnergyReceiver tileEntity) {
|
||||
super(tileEntity, "energy_handler");
|
||||
}
|
||||
|
||||
@Callback(doc = "function([direction:number=6]):number -- Returns the amount of stored energy for the given side.")
|
||||
public Object[] getEnergyStored(final Context context, final Arguments args) {
|
||||
final ForgeDirection side = args.count() > 0 ? ForgeDirection.getOrientation(args.checkInteger(0)) : ForgeDirection.UNKNOWN;
|
||||
return new Object[]{tileEntity.getEnergyStored(side)};
|
||||
}
|
||||
|
||||
@Callback(doc = "function([direction:number=6]):number -- Returns the maximum amount of stored energy for the given side.")
|
||||
public Object[] getMaxEnergyStored(final Context context, final Arguments args) {
|
||||
final ForgeDirection side = args.count() > 0 ? ForgeDirection.getOrientation(args.checkInteger(0)) : ForgeDirection.UNKNOWN;
|
||||
return new Object[]{tileEntity.getMaxEnergyStored(side)};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Returns whether this component can provide energy.")
|
||||
public Object[] isEnergyProvider(final Context context, final Arguments args) {
|
||||
return new Object[]{false};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Returns whether this component can receive energy.")
|
||||
public Object[] isEnergyReceiver(final Context context, final Arguments args) {
|
||||
return new Object[]{true};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +1,33 @@
|
||||
package li.cil.oc.integration.cofh.energy
|
||||
|
||||
import cpw.mods.fml.common.ModAPIManager
|
||||
import cpw.mods.fml.common.event.FMLInterModComms
|
||||
import cpw.mods.fml.common.versioning.VersionRange
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object ModCoFHEnergy extends ModProxy {
|
||||
override def getMod = Mods.CoFHEnergy
|
||||
|
||||
private val versionsUsingSplitEnergyAPI = VersionRange.createFromVersionSpec("[1.0.0,)")
|
||||
|
||||
override def initialize() {
|
||||
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.getDurability")
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(EventHandlerRedstoneFlux)
|
||||
|
||||
Driver.add(new DriverEnergyHandler)
|
||||
val apiVersion = ModAPIManager.INSTANCE.getAPIList.find(_.getModId == Mods.IDs.CoFHEnergy).map(_.getProcessedVersion)
|
||||
if (apiVersion.exists(versionsUsingSplitEnergyAPI.containsVersion)) {
|
||||
Driver.add(new DriverEnergyProvider)
|
||||
Driver.add(new DriverEnergyReceiver)
|
||||
}
|
||||
else {
|
||||
Driver.add(new DriverEnergyHandler)
|
||||
}
|
||||
|
||||
Driver.add(new ConverterEnergyContainerItem)
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
import scala.language.existentials
|
||||
|
||||
class Geolyzer(val host: EnvironmentHost) extends prefab.ManagedEnvironment {
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
|
@ -1,27 +1,15 @@
|
||||
package li.cil.oc.server.component
|
||||
|
||||
import java.io.BufferedWriter
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.io.{BufferedWriter, FileNotFoundException, IOException, InputStream, OutputStreamWriter}
|
||||
import java.net._
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.SocketChannel
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.{Callable, ConcurrentLinkedQueue, ExecutionException, Future}
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Network
|
||||
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.{OpenComputers, Settings, api}
|
||||
import li.cil.oc.api.machine.{Arguments, Callback, Context}
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.api.{Network, prefab}
|
||||
import li.cil.oc.api.prefab.AbstractValue
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ThreadPoolFactory
|
||||
@ -239,28 +227,30 @@ object InternetCard {
|
||||
})
|
||||
}
|
||||
|
||||
private def checkConnected() = try {
|
||||
private def checkConnected() = {
|
||||
if (owner.isEmpty) throw new IOException("connection lost")
|
||||
if (isAddressResolved) channel.finishConnect()
|
||||
else if (address.isCancelled) {
|
||||
// I don't think this can ever happen, Justin Case.
|
||||
channel.close()
|
||||
throw new IOException("bad connection descriptor")
|
||||
}
|
||||
else if (address.isDone) {
|
||||
// Check for errors.
|
||||
try address.get catch {
|
||||
case e: ExecutionException => throw e.getCause
|
||||
try {
|
||||
if (isAddressResolved) channel.finishConnect()
|
||||
else if (address.isCancelled) {
|
||||
// I don't think this can ever happen, Justin Case.
|
||||
channel.close()
|
||||
throw new IOException("bad connection descriptor")
|
||||
}
|
||||
isAddressResolved = true
|
||||
false
|
||||
else if (address.isDone) {
|
||||
// Check for errors.
|
||||
try address.get catch {
|
||||
case e: ExecutionException => throw e.getCause
|
||||
}
|
||||
isAddressResolved = true
|
||||
false
|
||||
}
|
||||
else false
|
||||
}
|
||||
catch {
|
||||
case t: Throwable =>
|
||||
close()
|
||||
false
|
||||
}
|
||||
else false
|
||||
}
|
||||
catch {
|
||||
case t: Throwable =>
|
||||
close()
|
||||
false
|
||||
}
|
||||
|
||||
// This has to be an explicit internal class instead of an anonymous one
|
||||
@ -430,6 +420,7 @@ object InternetCard {
|
||||
throw new IOException(Option(e.getMessage).getOrElse(e.toString))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,12 +2,16 @@ package li.cil.oc.server.component
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.Event
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.api.network.Message
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntitySign
|
||||
import net.minecraft.world.WorldServer
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
@ -62,4 +66,20 @@ abstract class UpgradeSign extends prefab.ManagedEnvironment {
|
||||
MinecraftForge.EVENT_BUS.post(event)
|
||||
!(event.isCanceled || event.getResult == Event.Result.DENY)
|
||||
}
|
||||
|
||||
override def onMessage(message: Message): Unit = {
|
||||
super.onMessage(message)
|
||||
if (message.name == "tablet.use") message.source.host match {
|
||||
case machine: api.machine.Machine => (machine.host, message.data) match {
|
||||
case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: ForgeDirection, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) =>
|
||||
host.world.getTileEntity(blockPos) match {
|
||||
case sign: TileEntitySign =>
|
||||
nbt.setString("signText", sign.signText.mkString("\n"))
|
||||
case _ =>
|
||||
}
|
||||
case _ => // Ignore.
|
||||
}
|
||||
case _ => // Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ 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.api.prefab
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.common.SaveHandler
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.tileentity
|
||||
@ -257,12 +258,21 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
false
|
||||
case _ =>
|
||||
state.push(Machine.State.Stopping)
|
||||
EventHandler.scheduleClose(this)
|
||||
true
|
||||
})
|
||||
|
||||
override def crash(message: String) = {
|
||||
this.message = Option(message)
|
||||
stop()
|
||||
state.synchronized {
|
||||
val result = stop()
|
||||
if (state.top == Machine.State.Stopping) {
|
||||
// When crashing, make sure there's no "Running" left in the stack.
|
||||
state.clear()
|
||||
state.push(Machine.State.Stopping)
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
override def signal(name: String, args: AnyRef*) = state.synchronized(state.top match {
|
||||
@ -392,6 +402,8 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def isExecuting = state.synchronized(state.contains(Machine.State.Running))
|
||||
|
||||
override val canUpdate = true
|
||||
|
||||
override def update() = if (state.synchronized(state.top != Machine.State.Stopped)) {
|
||||
@ -499,7 +511,9 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
state.pop() // Running, no switchTo to avoid new future.
|
||||
state.push(Machine.State.SynchronizedReturn)
|
||||
state.push(Machine.State.Paused)
|
||||
case Machine.State.Stopping => // Nothing to do, we'll die anyway.
|
||||
case Machine.State.Stopping =>
|
||||
state.clear()
|
||||
state.push(Machine.State.Stopping)
|
||||
case _ => throw new AssertionError()
|
||||
}
|
||||
}
|
||||
@ -514,7 +528,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
inSynchronizedCall = false
|
||||
}
|
||||
|
||||
assert(state.top != Machine.State.Running)
|
||||
assert(!isExecuting)
|
||||
case _ => // Nothing special to do, just avoid match errors.
|
||||
})
|
||||
|
||||
@ -643,7 +657,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
|
||||
super.load(nbt)
|
||||
|
||||
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
|
||||
state.pushAll(nbt.getIntArray("state").reverseMap(Machine.State(_)))
|
||||
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
||||
if (nbt.hasKey("message")) {
|
||||
message = Some(nbt.getString("message"))
|
||||
@ -703,7 +717,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound): Unit = Machine.this.synchronized {
|
||||
assert(state.top != Machine.State.Running) // Lock on 'this' should guarantee this.
|
||||
assert(!isExecuting) // Lock on 'this' should guarantee this.
|
||||
|
||||
// Make sure we don't continue running until everything has saved.
|
||||
pause(0.05)
|
||||
@ -798,16 +812,25 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
false
|
||||
}
|
||||
|
||||
def tryClose(): Boolean =
|
||||
if (isExecuting) false
|
||||
else {
|
||||
close()
|
||||
true
|
||||
}
|
||||
|
||||
private def close() = state.synchronized(
|
||||
if (state.size == 0 || state.top != Machine.State.Stopped) {
|
||||
state.clear()
|
||||
state.push(Machine.State.Stopped)
|
||||
Option(architecture).foreach(_.close())
|
||||
signals.clear()
|
||||
uptime = 0
|
||||
cpuTotal = 0
|
||||
cpuStart = 0
|
||||
remainIdle = 0
|
||||
this.synchronized {
|
||||
state.clear()
|
||||
state.push(Machine.State.Stopped)
|
||||
Option(architecture).foreach(_.close())
|
||||
signals.clear()
|
||||
uptime = 0
|
||||
cpuTotal = 0
|
||||
cpuStart = 0
|
||||
remainIdle = 0
|
||||
}
|
||||
|
||||
// Mark state change in owner, to send it to clients.
|
||||
host.markChanged()
|
||||
@ -906,10 +929,12 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
crash(Option(result.message).getOrElse("unknown error"))
|
||||
}
|
||||
state.push(Machine.State.Paused)
|
||||
case Machine.State.Stopping => // Nothing to do, we'll die anyway.
|
||||
case Machine.State.Stopping =>
|
||||
state.clear()
|
||||
state.push(Machine.State.Stopping)
|
||||
case _ => throw new AssertionError("Invalid state in executor post-processing.")
|
||||
}
|
||||
assert(state.top != Machine.State.Running)
|
||||
assert(!isExecuting)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
Loading…
x
Reference in New Issue
Block a user