From a59859b225e41cfd625eb3fccdc7e67988061788 Mon Sep 17 00:00:00 2001
From: payonel
Date: Wed, 10 Feb 2016 13:01:46 -0800
Subject: [PATCH 01/16] severe text split inefficiency found and fixed
---
.../opencomputers/loot/OpenOS/lib/text.lua | 51 +++++++++++--------
1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/text.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/text.lua
index 163afe255..3e5839bcf 100644
--- a/src/main/resources/assets/opencomputers/loot/OpenOS/lib/text.lua
+++ b/src/main/resources/assets/opencomputers/loot/OpenOS/lib/text.lua
@@ -118,31 +118,42 @@ function text.removeEscapes(txt)
end
-------------------------------------------------------------------------------
-
-function --[[@delayloaded-start@]] text.split(input, delimiters, dropDelims)
+function --[[@delayloaded-start@]] text.split(input, delimiters, dropDelims, di)
checkArg(1, input, "string")
checkArg(2, delimiters, "table")
checkArg(3, dropDelims, "boolean", "nil")
+ checkArg(4, di, "number", "nil")
- local input_table = text.internal.table_view(input)
- local delim_table = tx.select(delimiters, function(e,i,t)
- return text.internal.table_view(e)
- end)
- local parts = tx.partition(input_table, function(e,i,t)
- local ns, ne = tx.first(t,delim_table,i)
- if not ns or dropDelims or ns == i then
- return ns, ne
- else -- not droping delims and ns>i
- return i, ns-1
+ if #input == 0 then return {} end
+ di = di or 1
+ local result = {input}
+ if di > #delimiters then return result end
+
+ local function add(part, index, r, s, e)
+ local sub = part:sub(s,e)
+ if #sub == 0 then return index end
+ local subs = r and text.split(sub,delimiters,dropDelims,r) or {sub}
+ for i=1,#subs do
+ table.insert(result, index+i-1, subs[i])
end
- end, dropDelims)
- return tx.select(parts, function(e,i,t)
- local inner = ''
- tx.foreach(e, function(ee,ii,tt)
- inner = inner..ee
- end)
- return inner
- end)
+ return index+#subs
+ end
+
+ local i,d=1,delimiters[di]
+ while true do
+ local next = table.remove(result,i)
+ if not next then break end
+ local si,ei = next:find(d)
+ if si and ei and ei~=0 then -- delim found
+ i=add(next, i, di+1, 1, si-1)
+ i=dropDelims and i or add(next, i, false, si, ei)
+ i=add(next, i, di, ei+1)
+ else
+ i=add(next, i, di+1, 1, #next)
+ end
+ end
+
+ return result
end --[[@delayloaded-end@]]
-----------------------------------------------------------------------------
From c3a391d55821a17735de6481fe777e0a41aae836 Mon Sep 17 00:00:00 2001
From: payonel
Date: Fri, 5 Feb 2016 20:36:24 -0800
Subject: [PATCH 02/16] fix cp one file system option
one file system check allows recursive copy where the path is the parent of the destination but said paths are on different file systems
---
.../resources/assets/opencomputers/loot/OpenOS/bin/cp.lua | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
index ebca97702..1ae53daaa 100644
--- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
+++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
@@ -66,17 +66,17 @@ local function recurse(fromPath, toPath, origin)
io.write("omitting directory `" .. fromPath .. "'\n")
return true
end
- if fs.canonical(fs.path(toPath)):find(fs.canonical(fromPath),1,true) then
- return nil, "cannot copy a directory, `" .. fromPath .. "', into itself, `" .. toPath .. "'"
- end
if fs.exists(toPath) and not fs.isDirectory(toPath) then
-- my real cp always does this, even with -f, -n or -i.
return nil, "cannot overwrite non-directory `" .. toPath .. "' with directory `" .. fromPath .. "'"
end
- fs.makeDirectory(toPath)
if options.x and origin and fs.get(fromPath) ~= origin then
return true
end
+ if fs.get(fromPath) == fs.get(toPath) and fs.canonical(fs.path(toPath)):find(fs.canonical(fromPath),1,true) then
+ return nil, "cannot copy a directory, `" .. fromPath .. "', into itself, `" .. toPath .. "'"
+ end
+ fs.makeDirectory(toPath)
for file in fs.list(fromPath) do
local result, reason = recurse(fs.concat(fromPath, file), fs.concat(toPath, file), origin or fs.get(fromPath))
if not result then
From d9bd0096beccf78f85409a889e1b2fbf47102905 Mon Sep 17 00:00:00 2001
From: payonel
Date: Thu, 11 Feb 2016 23:03:44 -0800
Subject: [PATCH 03/16] fixing cp -x
---
.../resources/assets/opencomputers/loot/OpenOS/bin/cp.lua | 7 ++++++-
.../assets/opencomputers/loot/OpenOS/bin/install.lua | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
index 1ae53daaa..bbeed1f81 100644
--- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
+++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/cp.lua
@@ -59,6 +59,11 @@ local function areEqual(path1, path2)
return result
end
+local mounts = {}
+for dev,path in fs.mounts() do
+ mounts[fs.canonical(path)] = dev
+end
+
local function recurse(fromPath, toPath, origin)
status(fromPath, toPath)
if fs.isDirectory(fromPath) then
@@ -70,7 +75,7 @@ local function recurse(fromPath, toPath, origin)
-- my real cp always does this, even with -f, -n or -i.
return nil, "cannot overwrite non-directory `" .. toPath .. "' with directory `" .. fromPath .. "'"
end
- if options.x and origin and fs.get(fromPath) ~= origin then
+ if options.x and origin and mounts[fs.canonical(fromPath)] then
return true
end
if fs.get(fromPath) == fs.get(toPath) and fs.canonical(fs.path(toPath)):find(fs.canonical(fromPath),1,true) then
diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/install.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/install.lua
index 95ae88c66..940eddbd3 100644
--- a/src/main/resources/assets/opencomputers/loot/OpenOS/bin/install.lua
+++ b/src/main/resources/assets/opencomputers/loot/OpenOS/bin/install.lua
@@ -60,7 +60,7 @@ io.write("Installing " .. name .." to device " .. (choice.getLabel() or choice.a
os.sleep(0.25)
local cpPath = filesystem.concat(findMount(filesystem.get(os.getenv("_")).address), "bin/cp")
local cpOptions = "-vrx" .. (options.u and "ui " or "")
-local cpSource = filesystem.concat(findMount(fromAddress), options.fromDir or "/", "*")
+local cpSource = filesystem.concat(findMount(fromAddress), options.fromDir or "/")
local cpDest = findMount(choice.address) .. "/"
local result, reason = os.execute(cpPath .. " " .. cpOptions .. " " .. cpSource .. " " .. cpDest)
if not result then
From 590ecebc33ff7a7c948e4893b66f1a269bec8ef0 Mon Sep 17 00:00:00 2001
From: DrummerMC
Date: Sun, 14 Feb 2016 00:07:40 +0100
Subject: [PATCH 04/16] Add ThaumicEnergistics support
---
build.gradle | 5 +++
build.properties | 2 ++
.../scala/li/cil/oc/integration/Mods.scala | 3 ++
.../DriverBlockInterface.scala | 27 +++++++++++++++
.../thaumicenergistics/DriverController.scala | 33 +++++++++++++++++++
.../ModThaumicEnergistics.scala | 18 ++++++++++
.../thaumicenergistics/NetworkControl.scala | 24 ++++++++++++++
.../ThaumicEnergisticsUtils.scala | 12 +++++++
8 files changed, 124 insertions(+)
create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverBlockInterface.scala
create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverController.scala
create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala
create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
diff --git a/build.gradle b/build.gradle
index 554a4681a..b42691e08 100644
--- a/build.gradle
+++ b/build.gradle
@@ -167,6 +167,10 @@ repositories {
name 'ExtraCells'
artifactPattern "http://addons-origin.cursecdn.com/files/${config.ec.cf}/[module]-[revision].[ext]"
}
+ ivy {
+ name 'ThaumicEnergistics'
+ artifactPattern "http://addons-origin.cursecdn.com/files/${config.thaumicenergistics.cf}/[module]-[revision].[ext]"
+ }
}
configurations {
@@ -213,6 +217,7 @@ dependencies {
provided name: 'Railcraft', version: config.rc.version, ext: 'jar'
provided name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar'
provided name: 'ExtraCells', version: config.ec.version, ext: 'jar'
+ provided name: 'ThaumicEnergistics', version: config.thaumicenergistics.version, ext: 'jar'
compile 'com.google.code.findbugs:jsr305:1.3.9' // Annotations used by google libs.
diff --git a/build.properties b/build.properties
index 5fdcee916..75cf9574f 100644
--- a/build.properties
+++ b/build.properties
@@ -40,6 +40,8 @@ rc.cf=2219/321
rc.version=1.7.10-9.4.0.0
redlogic.version=59.0.3
rotc.version=V5c
+thaumicenergistics.cf=2277/520
+thaumicenergistics.version=1.0.0.1-RV2
tis3d.version=MC1.7.10-0.7.1.53
tmech.version=75.0afb56c
re.version=3.0.0.342
diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala
index 8fde28065..2bfe1e7f5 100644
--- a/src/main/scala/li/cil/oc/integration/Mods.scala
+++ b/src/main/scala/li/cil/oc/integration/Mods.scala
@@ -76,6 +76,7 @@ object Mods {
override def isModAvailable: Boolean = isModAvailable_
}
val Thaumcraft = new SimpleMod(IDs.Thaumcraft)
+ val ThaumicEnergistics = new SimpleMod(IDs.ThaumicEnergistics)
val ThermalExpansion = new SimpleMod(IDs.ThermalExpansion, providesPower = true)
val TinkersConstruct = new SimpleMod(IDs.TinkersConstruct)
val TIS3D = new SimpleMod(IDs.TIS3D, version = "@[0.7,)")
@@ -122,6 +123,7 @@ object Mods {
integration.rotarycraft.ModRotaryCraft,
integration.stargatetech2.ModStargateTech2,
integration.thaumcraft.ModThaumcraft,
+ integration.thaumicenergistics.ModThaumicEnergistics,
integration.thermalexpansion.ModThermalExpansion,
integration.tcon.ModTinkersConstruct,
integration.tis3d.ModTIS3D,
@@ -214,6 +216,7 @@ object Mods {
final val RotaryCraft = "RotaryCraft"
final val StargateTech2 = "StargateTech2"
final val Thaumcraft = "Thaumcraft"
+ final val ThaumicEnergistics = "thaumicenergistics"
final val ThermalExpansion = "ThermalExpansion"
final val TinkersConstruct = "TConstruct"
final val TIS3D = "tis3d"
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverBlockInterface.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverBlockInterface.scala
new file mode 100644
index 000000000..3ee7429c3
--- /dev/null
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverBlockInterface.scala
@@ -0,0 +1,27 @@
+package li.cil.oc.integration.thaumicenergistics
+
+import appeng.tile.misc.TileInterface
+import li.cil.oc.api.driver.EnvironmentProvider
+import li.cil.oc.api.network.ManagedEnvironment
+import li.cil.oc.api.prefab.DriverTileEntity
+import li.cil.oc.integration.ManagedTileEntityEnvironment
+import li.cil.oc.integration.appeng.AEUtil
+import net.minecraft.item.ItemStack
+import net.minecraft.world.World
+
+object DriverBlockInterface extends DriverTileEntity {
+ def getTileEntityClass: Class[_] = classOf[TileInterface]
+
+ def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment =
+ new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileInterface])
+
+ final class Environment(val tile: TileInterface) extends ManagedTileEntityEnvironment[TileInterface](tile, "me_interface") with NetworkControl[TileInterface]
+
+ object Provider extends EnvironmentProvider {
+ override def getEnvironment(stack: ItemStack): Class[_] =
+ if (AEUtil.isBlockInterface(stack))
+ classOf[Environment]
+ else null
+ }
+
+}
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverController.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverController.scala
new file mode 100644
index 000000000..8a0e90053
--- /dev/null
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/DriverController.scala
@@ -0,0 +1,33 @@
+package li.cil.oc.integration.thaumicenergistics
+
+import appeng.api.networking.security.IActionHost
+import appeng.me.helpers.IGridProxyable
+import li.cil.oc.api.driver.EnvironmentProvider
+import li.cil.oc.api.network.ManagedEnvironment
+import li.cil.oc.api.prefab.DriverTileEntity
+import li.cil.oc.integration.ManagedTileEntityEnvironment
+import li.cil.oc.integration.appeng.AEUtil
+import net.minecraft.item.ItemStack
+import net.minecraft.tileentity.TileEntity
+import net.minecraft.world.World
+
+import scala.language.existentials
+
+object DriverController extends DriverTileEntity {
+ private type TileController = TileEntity with IGridProxyable with IActionHost
+
+ def getTileEntityClass = AEUtil.controllerClass
+
+ def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment =
+ new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileController])
+
+ final class Environment(val tile: TileController) extends ManagedTileEntityEnvironment[TileController](tile, "me_controller") with NetworkControl[TileController]
+
+ object Provider extends EnvironmentProvider {
+ override def getEnvironment(stack: ItemStack): Class[_] =
+ if (AEUtil.isController(stack))
+ classOf[Environment]
+ else null
+ }
+
+}
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala
new file mode 100644
index 000000000..7eb2cf180
--- /dev/null
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala
@@ -0,0 +1,18 @@
+package li.cil.oc.integration.thaumicenergistics
+
+import li.cil.oc.api.Driver
+import li.cil.oc.integration.Mod
+import li.cil.oc.integration.ModProxy
+import li.cil.oc.integration.Mods
+
+object ModThaumicEnergistics extends ModProxy {
+ override def getMod: Mod = Mods.ThaumicEnergistics
+
+ override def initialize(): Unit = {
+ Driver.add(DriverController)
+ Driver.add(DriverBlockInterface)
+
+ Driver.add(DriverController.Provider)
+ Driver.add(DriverBlockInterface.Provider)
+ }
+}
\ No newline at end of file
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
new file mode 100644
index 000000000..778cc648f
--- /dev/null
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
@@ -0,0 +1,24 @@
+package li.cil.oc.integration.thaumicenergistics
+
+import appeng.api.networking.security.IActionHost
+import appeng.me.helpers.IGridProxyable
+import extracells.api.ECApi
+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.util.ResultWrapper._
+import net.minecraft.tileentity.TileEntity
+import thaumicenergistics.api.IThEEssentiaGas
+
+import scala.collection.convert.WrapAsScala._
+
+// Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it.
+trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] {
+ def tile: AETile
+
+ @Callback(doc = "function():table -- Get a list of the stored essentia in the network.")
+ def getEssentiaInNetwork(context: Context, args: Arguments): Array[AnyRef] =
+ result(tile.getProxy.getStorage.getFluidInventory.getStorageList.filter(stack =>
+ stack.getFluid != null && stack.getFluid.isInstanceOf[IThEEssentiaGas]).
+ map(ThaumicEnergisticsUtils.getAspect).toArray)
+}
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
new file mode 100644
index 000000000..aa9ee8f77
--- /dev/null
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
@@ -0,0 +1,12 @@
+package li.cil.oc.integration.thaumicenergistics
+
+import appeng.api.storage.data.IAEFluidStack
+
+
+object ThaumicEnergisticsUtils {
+ def getAspect(fluid: IAEFluidStack) ={
+ val aspect = fluid.getFluidStack.copy()
+ aspect.amount = (fluid.getStackSize / 128).toInt
+ aspect
+ }
+}
From f76f2448c709144aa75da1d4a78a35f2ce0fbac8 Mon Sep 17 00:00:00 2001
From: DrummerMC
Date: Sun, 14 Feb 2016 13:06:24 +0100
Subject: [PATCH 05/16] Disable ThaumicEnergistics by default
---
src/main/resources/application.conf | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf
index 111aa3677..5f0977cdd 100644
--- a/src/main/resources/application.conf
+++ b/src/main/resources/application.conf
@@ -1336,7 +1336,8 @@ opencomputers {
# computers (such as magic related mods, which is why Thaumcraft is on this
# list by default.)
modBlacklist: [
- "Thaumcraft"
+ "Thaumcraft",
+ "thaumicenergistics"
]
# A list of tile entities by class name that should NOT be accessible via
From f5d347e2e2fc98f01b26c48fd8c1b4a068ea12bc Mon Sep 17 00:00:00 2001
From: tim4242
Date: Sat, 20 Feb 2016 17:50:56 +0100
Subject: [PATCH 06/16] Modernized PetRenderer
- Made player checking UUID based
- Made in inventory detection better
---
.../cil/oc/client/renderer/PetRenderer.scala | 33 ++++++++++---------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
index 35eceac22..c08b8eced 100644
--- a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
+++ b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
@@ -26,16 +26,16 @@ object PetRenderer {
// http://goo.gl/frLWYR
private val entitledPlayers = Map(
- "Sangar" ->(0.3, 0.9, 0.6),
- "Jodarion" ->(1.0, 0.0, 0.0),
- "DaKaTotal" ->(0.5, 0.7, 1.0),
- "MichiRavencroft" ->(1.0, 0.0, 0.0),
- "Vexatos" ->(0.18, 0.95, 0.922),
- "StoneNomad" ->(0.8, 0.77, 0.75),
- "LizzyTheSiren" ->(0.3, 0.3, 1.0),
- "vifino" ->(0.2, 1.0, 0.1),
- "Izaya" ->(0.0, 0.2, 0.6),
- "Wobbo" ->(0.098, 0.471, 0.784)
+ "9f1f262f-0d68-4e13-9161-9eeaf4a0a1a8" ->(0.3, 0.9, 0.6), //Sangar
+ "18f8bed4-f027-44af-8947-6a3a2317645a" ->(1.0, 0.0, 0.0), //Jodarion
+ "36123742-2cf6-4cfc-8b65-278581b3caeb" ->(0.5, 0.7, 1.0), //DaKaTotal
+ "2c0c214b-96f4-4565-b513-de90d5fbc977" ->(1.0, 0.0, 0.0), //MichiRavencroft
+ "f3ba6ec8-c280-4950-bb08-1fcb2eab3a9c" ->(0.18, 0.95, 0.922), //Vexatos
+ "9d636bdd-b9f4-4b80-b9ce-586ca04bd4f3" ->(0.8, 0.77, 0.75), //StoneNomad
+ "23c7ed71-fb13-4abe-abe7-f355e1de6e62" ->(0.3, 0.3, 1.0), //LizzyTheSiren
+ "076541f1-f10a-46de-a127-dfab8adfbb75" ->(0.2, 1.0, 0.1), //vifino
+ "e7e90198-0ccf-4662-a827-192ec8f4419d" ->(0.0, 0.2, 0.6), //Izaya
+ "f514ee69-7bbb-4e46-9e94-d8176324cec2" ->(0.098, 0.471, 0.784) //Wobbo
)
private val petLocations = com.google.common.cache.CacheBuilder.newBuilder().
@@ -47,9 +47,9 @@ object PetRenderer {
@SubscribeEvent
def onPlayerRender(e: RenderPlayerEvent.Pre) {
- val name = e.entityPlayer.getCommandSenderName
- if (hidden.contains(name) || !entitledPlayers.contains(name)) return
- rendering = Some(entitledPlayers(name))
+ val uuid = e.entityPlayer.getUniqueID.toString
+ if (hidden.contains(uuid) || !entitledPlayers.contains(uuid)) return
+ rendering = Some(entitledPlayers(uuid))
val worldTime = e.entityPlayer.getEntityWorld.getTotalWorldTime
val timeJitter = e.entityPlayer.hashCode ^ 0xFF
@@ -143,8 +143,11 @@ object PetRenderer {
GL11.glTranslated(0.3, -0.1, -0.2)
}
- // Someone please tell me a cleaner solution than this...
- private def isForInventory = new Exception().getStackTrace.exists(_.getClassName == classOf[GuiContainer].getName)
+ //Sangar: Someone please tell me a cleaner solution than this...
+ //tim4242: This seems to be cleaner, but what do I know?
+ private def isForInventory = Minecraft.getMinecraft.currentScreen != null && owner == Minecraft.getMinecraft.thePlayer //Check if the player is currently in an inventory
+ //private def isForInventory = new Exception().getStackTrace.exists(_.getClassName == classOf[GuiContainer].getName)
+
}
@SubscribeEvent
From 726ceae91f5edc1f997cadd62bab6c1cf80ec565 Mon Sep 17 00:00:00 2001
From: Vexatos
Date: Mon, 22 Feb 2016 14:25:03 +0100
Subject: [PATCH 07/16] Made Hover Boots dyeable.
---
.../textures/items/HoverBoots.png | Bin 461 -> 420 bytes
.../textures/items/HoverBootsLight.png | Bin 0 -> 198 bytes
.../renderer/item/HoverBootRenderer.scala | 7 +-
.../li/cil/oc/common/item/HoverBoots.scala | 43 ++++++---
.../cil/oc/common/recipe/ColorizeRecipe.scala | 85 ++++++++++++++++++
.../oc/common/recipe/DecolorizeRecipe.scala | 44 +++++++++
.../li/cil/oc/common/recipe/Recipes.scala | 6 ++
.../scala/li/cil/oc/util/ItemColorizer.scala | 47 ++++++++++
8 files changed, 221 insertions(+), 11 deletions(-)
create mode 100644 src/main/resources/assets/opencomputers/textures/items/HoverBootsLight.png
create mode 100644 src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
create mode 100644 src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
create mode 100644 src/main/scala/li/cil/oc/util/ItemColorizer.scala
diff --git a/src/main/resources/assets/opencomputers/textures/items/HoverBoots.png b/src/main/resources/assets/opencomputers/textures/items/HoverBoots.png
index 0096a1ccd3efc4d3497d3fe6abee70ce87e9c6cb..1a7f2d070ee59d2138e4a1f20b67a63ba06ebb37 100644
GIT binary patch
delta 273
zcmX@hyo7mzibz+0Pl#*9r3!IF@(X5gcy=QV
z#7XjYcVXyYmGuB}I14-?iy0WWg+Z8+Vb&Z8pdfpRr>`sf112#Z1+JBu_ih4(CVRR#
zhDcnF?Z3{~Y{28X_k=)T1CwaLt`~Cu|JU;BY6^Y-_~XSbwg|Tu3(sXQWcEKWWBRF%
zj3V)anYT@pzI(^IFW%*7P$Or(p`Kakn=6ak)`gSS{*?}uX8FXpW|D}Yk6lX6L~f5`
zJDI0;PI$h@!&!6zo9aW3^Vcu3zhUU}*E{{!|N873b9}0Ne#Krt%fG0&>YDgZhCAwP
Vq1{|=OhETBc)I$ztaD0e0sv7uW)}be
delta 314
zcmZ3&e3p5Filt3VtQ&&YGO)d;mK4R1_p+%0G|+7
zaYN&nFbijU&7vIdic1v}EvoC!Y&5z9l-4T=@(cb?3SemJFAfFjobT!47*cU7rthXu
zlL3$G
diff --git a/src/main/resources/assets/opencomputers/textures/items/HoverBootsLight.png b/src/main/resources/assets/opencomputers/textures/items/HoverBootsLight.png
new file mode 100644
index 0000000000000000000000000000000000000000..f231225103e75edf8ef897d1f5d359ca9af2133e
GIT binary patch
literal 198
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b
z3=G`DAk4@xYmNj^kiEpy*OmPNlNgVR*`uuVD4P0|!35y=~400=2cZkG{t5t@>);Q~UAJ(f=vdKfk=Z{J--XQ|z3ct4F%U_5c0<
l`dWNWepc2gi;ByP3=*5wT+HQO{RbM);OXk;vd$@?2>{JkNGkvU
literal 0
HcmV?d00001
diff --git a/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala
index b82ebd7cf..243308b3a 100644
--- a/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala
+++ b/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala
@@ -92,6 +92,8 @@ object HoverBootRenderer extends ModelBiped {
bipedEars.isHidden = true
bipedCloak.isHidden = true
+ var lightColor = 0x66DD55
+
override def render(entity: Entity, f0: Float, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = {
// Because Forge is being a dummy...
isSneak = entity.isSneaking
@@ -104,7 +106,10 @@ object HoverBootRenderer extends ModelBiped {
RenderState.disableLighting()
GL11.glDepthFunc(GL11.GL_LEQUAL)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE)
- GL11.glColor3ub(0x66.toByte, 0xDD.toByte, 0x55.toByte)
+ val r = ((lightColor >>> 16) & 0xFF).toByte
+ val g = ((lightColor >>> 8) & 0xFF).toByte
+ val b = ((lightColor >>> 0) & 0xFF).toByte
+ GL11.glColor3ub(r, g, b)
super.render(dt)
diff --git a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
index 81fc13bfd..10593e2a1 100644
--- a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
+++ b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
@@ -1,19 +1,17 @@
package li.cil.oc.common.item
-import cpw.mods.fml.relauncher.Side
-import cpw.mods.fml.relauncher.SideOnly
+import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.Settings
import li.cil.oc.client.renderer.item.HoverBootRenderer
import li.cil.oc.common.item.data.HoverBootsData
+import li.cil.oc.util.ItemColorizer
import net.minecraft.client.model.ModelBiped
-import net.minecraft.entity.Entity
-import net.minecraft.entity.EntityLivingBase
+import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
-import net.minecraft.item.EnumRarity
-import net.minecraft.item.ItemArmor
-import net.minecraft.item.ItemStack
-import net.minecraft.potion.Potion
-import net.minecraft.potion.PotionEffect
+import net.minecraft.entity.{Entity, EntityLivingBase}
+import net.minecraft.item.{EnumRarity, ItemArmor, ItemStack}
+import net.minecraft.potion.{Potion, PotionEffect}
+import net.minecraft.util.IIcon
import net.minecraft.world.World
class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with traits.SimpleItem with traits.Chargeable {
@@ -56,7 +54,10 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
@SideOnly(Side.CLIENT)
override def getArmorModel(entityLiving: EntityLivingBase, itemStack: ItemStack, armorSlot: Int): ModelBiped = {
- if (armorSlot == armorType) HoverBootRenderer
+ if (armorSlot == armorType) {
+ HoverBootRenderer.lightColor = if (ItemColorizer.hasColor(itemStack)) ItemColorizer.getColor(itemStack) else 0x66DD55
+ HoverBootRenderer
+ }
else super.getArmorModel(entityLiving, itemStack, armorSlot)
}
@@ -72,6 +73,28 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
}
}
+ @SideOnly(Side.CLIENT)
+ var lightOverlay: IIcon = null
+
+ @SideOnly(Side.CLIENT)
+ override def registerIcons(ir: IIconRegister): Unit = {
+ this.itemIcon = ir.registerIcon(this.getIconString)
+ this.lightOverlay = ir.registerIcon(this.getIconString + "Light")
+ }
+
+ @SideOnly(Side.CLIENT)
+ override def requiresMultipleRenderPasses(): Boolean = true
+
+ @SideOnly(Side.CLIENT)
+ override def getIconFromDamageForRenderPass(meta : Int, pass : Int): IIcon = if (pass == 1 ) lightOverlay else super.getIconFromDamageForRenderPass(meta, pass)
+
+ override def getColorFromItemStack(itemStack: ItemStack, pass: Int): Int = {
+ if (pass == 1) {
+ return if (ItemColorizer.hasColor(itemStack)) ItemColorizer.getColor(itemStack) else 0x66DD55
+ }
+ super.getColorFromItemStack(itemStack, pass)
+ }
+
override def getDisplayDamage(stack: ItemStack): Int = {
val data = new HoverBootsData(stack)
(Settings.get.bufferHoverBoots * (1 - data.charge / Settings.get.bufferHoverBoots)).toInt
diff --git a/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
new file mode 100644
index 000000000..74a95919c
--- /dev/null
+++ b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
@@ -0,0 +1,85 @@
+package li.cil.oc.common.recipe
+
+import li.cil.oc.util.{Color, ItemColorizer}
+import net.minecraft.entity.passive.EntitySheep
+import net.minecraft.inventory.InventoryCrafting
+import net.minecraft.item.crafting.IRecipe
+import net.minecraft.item.{Item, ItemStack}
+import net.minecraft.world.World
+
+/**
+ * @author asie, Vexatos
+ */
+class ColorizeRecipe(target: Item, source: Array[Item] = null) extends IRecipe {
+ val targetItem = target
+ val sourceItems = if (source != null) source else Array(targetItem)
+
+ override def matches(crafting: InventoryCrafting, world: World): Boolean = {
+ val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
+ val targets = stacks.filter(stack => sourceItems.contains(stack.getItem) || stack.getItem == targetItem)
+ val other = stacks.filterNot(targets.contains)
+ targets.size == 1 && other.nonEmpty && other.forall(Color.isDye)
+ }
+
+ override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
+ var targetStack: ItemStack = null
+ val color = Array[Int](0, 0, 0)
+ var colorCount = 0
+ var maximum = 0
+
+ (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
+ if (sourceItems.contains(stack.getItem)
+ || stack.getItem == targetItem) {
+ targetStack = stack.copy()
+ targetStack.stackSize = 1
+ } else {
+ val dye = Color.findDye(stack)
+ if (dye.isEmpty)
+ return null
+
+ val itemColor = EntitySheep.fleeceColorTable(15 - Color.dyes.indexOf(dye.get))
+ val red = (itemColor(0) * 255.0F).toInt
+ val green = (itemColor(1) * 255.0F).toInt
+ val blue = (itemColor(2) * 255.0F).toInt
+ maximum += Math.max(red, Math.max(green, blue))
+ color(0) += red
+ color(1) += green
+ color(2) += blue
+ colorCount = colorCount + 1
+ }
+ }
+
+ if (targetStack == null) return null
+
+ if (targetItem == targetStack.getItem) {
+ if (ItemColorizer.hasColor(targetStack)) {
+ val itemColor = ItemColorizer.getColor(targetStack)
+ val red = (itemColor >> 16 & 255).toFloat / 255.0F
+ val green = (itemColor >> 8 & 255).toFloat / 255.0F
+ val blue = (itemColor & 255).toFloat / 255.0F
+ maximum = (maximum.toFloat + Math.max(red, Math.max(green, blue)) * 255.0F).toInt
+ color(0) = (color(0).toFloat + red * 255.0F).toInt
+ color(1) = (color(1).toFloat + green * 255.0F).toInt
+ color(2) = (color(2).toFloat + blue * 255.0F).toInt
+ colorCount = colorCount + 1
+ }
+ } else if (sourceItems.contains(targetStack.getItem)) {
+ targetStack = new ItemStack(targetItem, targetStack.stackSize, targetStack.getItemDamage)
+ }
+
+ var red = color(0) / colorCount
+ var green = color(1) / colorCount
+ var blue = color(2) / colorCount
+ val max = maximum.toFloat / colorCount.toFloat
+ val div = Math.max(red, Math.max(green, blue)).toFloat
+ red = (red.toFloat * max / div).toInt
+ green = (green.toFloat * max / div).toInt
+ blue = (blue.toFloat * max / div).toInt
+ ItemColorizer.setColor(targetStack, (red << 16) | (green << 8) | blue)
+ targetStack
+ }
+
+ override def getRecipeSize = 10
+
+ override def getRecipeOutput = null
+}
diff --git a/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
new file mode 100644
index 000000000..f6cdb547a
--- /dev/null
+++ b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
@@ -0,0 +1,44 @@
+package li.cil.oc.common.recipe
+
+import li.cil.oc.util.ItemColorizer
+import net.minecraft.init.Items
+import net.minecraft.inventory.InventoryCrafting
+import net.minecraft.item.crafting.IRecipe
+import net.minecraft.item.{Item, ItemStack}
+import net.minecraft.world.World
+
+/**
+ * @author Vexatos
+ */
+class DecolorizeRecipe(target: Item) extends IRecipe {
+ val targetItem = target
+
+ override def matches(crafting: InventoryCrafting, world: World): Boolean = {
+ val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
+ val targets = stacks.filter(stack => stack.getItem == targetItem)
+ val other = stacks.filterNot(targets.contains)
+ targets.size == 1 && other.size == 1 && other.forall(_.getItem == Items.water_bucket)
+ }
+
+ override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
+ var targetStack: ItemStack = null
+
+ (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
+ if (stack.getItem == targetItem) {
+ targetStack = stack.copy()
+ targetStack.stackSize = 1
+ } else if (stack.getItem != Items.water_bucket) {
+ return null
+ }
+ }
+
+ if (targetStack == null) return null
+
+ ItemColorizer.removeColor(targetStack)
+ targetStack
+ }
+
+ override def getRecipeSize = 10
+
+ override def getRecipeOutput = null
+}
diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
index 9e1aa47e8..2a6e986be 100644
--- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
@@ -89,6 +89,8 @@ object Recipes {
def init() {
RecipeSorter.register(Settings.namespace + "extshaped", classOf[ExtendedShapedOreRecipe], Category.SHAPED, "after:forge:shapedore")
RecipeSorter.register(Settings.namespace + "extshapeless", classOf[ExtendedShapelessOreRecipe], Category.SHAPELESS, "after:forge:shapelessore")
+ RecipeSorter.register(Settings.namespace + "colorizer", classOf[ColorizeRecipe], Category.SHAPELESS, "after:forge:shapelessore")
+ RecipeSorter.register(Settings.namespace + "decolorizer", classOf[DecolorizeRecipe], Category.SHAPELESS, "after:oc:decolorizer")
for ((name, stack) <- oreDictEntries) {
if (!OreDictionary.getOres(name).contains(stack)) {
@@ -322,6 +324,10 @@ object Recipes {
api.Items.get(Constants.BlockName.AccessPoint).createItemStack(1))
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
api.Items.get(Constants.BlockName.Switch).createItemStack(1))
+
+ // Hover Boot dyeing
+ GameRegistry.addRecipe(new ColorizeRecipe(api.Items.get(Constants.ItemName.HoverBoots).item()))
+ GameRegistry.addRecipe(new DecolorizeRecipe(api.Items.get(Constants.ItemName.HoverBoots).item()))
}
catch {
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)
diff --git a/src/main/scala/li/cil/oc/util/ItemColorizer.scala b/src/main/scala/li/cil/oc/util/ItemColorizer.scala
new file mode 100644
index 000000000..7043d29ce
--- /dev/null
+++ b/src/main/scala/li/cil/oc/util/ItemColorizer.scala
@@ -0,0 +1,47 @@
+package li.cil.oc.util
+
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagCompound
+
+/**
+ * @author asie, Vexatos
+ */
+object ItemColorizer {
+ /**
+ * Return whether the specified armor ItemStack has a color.
+ */
+ def hasColor(stack: ItemStack): Boolean = stack.hasTagCompound && stack.getTagCompound.hasKey("display") && stack.getTagCompound.getCompoundTag("display").hasKey("color")
+
+ /**
+ * Return the color for the specified armor ItemStack.
+ */
+ def getColor(stack: ItemStack): Int = {
+ val tag = stack.getTagCompound
+ if (tag != null) {
+ val displayTag = tag.getCompoundTag("display")
+ if (displayTag == null) -1 else if (displayTag.hasKey("color")) displayTag.getInteger("color") else -1
+ }
+ else -1
+ }
+
+ def removeColor(stack: ItemStack) {
+ val tag = stack.getTagCompound
+ if (tag != null) {
+ val displayTag = tag.getCompoundTag("display")
+ if (displayTag.hasKey("color")) displayTag.removeTag("color")
+ }
+ }
+
+ def setColor(stack: ItemStack, color: Int) {
+ var tag = stack.getTagCompound
+ if (tag == null) {
+ tag = new NBTTagCompound
+ stack.setTagCompound(tag)
+ }
+ val displayTag = tag.getCompoundTag("display")
+ if (!tag.hasKey("display")) {
+ tag.setTag("display", displayTag)
+ }
+ displayTag.setInteger("color", color)
+ }
+}
From 1f13395dccd68f889d6e4631633960442fe6c8f1 Mon Sep 17 00:00:00 2001
From: Vexatos
Date: Mon, 22 Feb 2016 22:10:33 +0100
Subject: [PATCH 08/16] Made hover boots lose their colour when tossed into a
cauldron.
---
.../li/cil/oc/common/item/HoverBoots.scala | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
index 10593e2a1..abc28fb90 100644
--- a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
+++ b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
@@ -7,11 +7,13 @@ import li.cil.oc.common.item.data.HoverBootsData
import li.cil.oc.util.ItemColorizer
import net.minecraft.client.model.ModelBiped
import net.minecraft.client.renderer.texture.IIconRegister
+import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.entity.{Entity, EntityLivingBase}
+import net.minecraft.init.Blocks
import net.minecraft.item.{EnumRarity, ItemArmor, ItemStack}
import net.minecraft.potion.{Potion, PotionEffect}
-import net.minecraft.util.IIcon
+import net.minecraft.util.{IIcon, MathHelper}
import net.minecraft.world.World
class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with traits.SimpleItem with traits.Chargeable {
@@ -73,6 +75,23 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
}
}
+ override def onEntityItemUpdate(entity: EntityItem): Boolean = {
+ if (entity != null && entity.worldObj != null && !entity.worldObj.isRemote && ItemColorizer.hasColor(entity.getEntityItem)) {
+ val x = MathHelper.floor_double(entity.posX)
+ val y = MathHelper.floor_double(entity.posY)
+ val z = MathHelper.floor_double(entity.posZ)
+ if (entity.worldObj.getBlock(x, y, z) == Blocks.cauldron) {
+ val meta = entity.worldObj.getBlockMetadata(x, y, z)
+ if (meta > 0) {
+ ItemColorizer.removeColor(entity.getEntityItem)
+ entity.worldObj.setBlockMetadataWithNotify(x, y, z, meta - 1, 3)
+ return true
+ }
+ }
+ }
+ super.onEntityItemUpdate(entity)
+ }
+
@SideOnly(Side.CLIENT)
var lightOverlay: IIcon = null
@@ -86,7 +105,7 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
override def requiresMultipleRenderPasses(): Boolean = true
@SideOnly(Side.CLIENT)
- override def getIconFromDamageForRenderPass(meta : Int, pass : Int): IIcon = if (pass == 1 ) lightOverlay else super.getIconFromDamageForRenderPass(meta, pass)
+ override def getIconFromDamageForRenderPass(meta: Int, pass: Int): IIcon = if (pass == 1) lightOverlay else super.getIconFromDamageForRenderPass(meta, pass)
override def getColorFromItemStack(itemStack: ItemStack, pass: Int): Int = {
if (pass == 1) {
From b2105d9963daa7d50bd85baf48822a3208a26327 Mon Sep 17 00:00:00 2001
From: Vexatos
Date: Mon, 22 Feb 2016 22:42:59 +0100
Subject: [PATCH 09/16] Added information on dyeing to the manual.
---
.../resources/assets/opencomputers/doc/en_US/item/hoverBoots.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/main/resources/assets/opencomputers/doc/en_US/item/hoverBoots.md b/src/main/resources/assets/opencomputers/doc/en_US/item/hoverBoots.md
index 444dca718..8ff8a375d 100644
--- a/src/main/resources/assets/opencomputers/doc/en_US/item/hoverBoots.md
+++ b/src/main/resources/assets/opencomputers/doc/en_US/item/hoverBoots.md
@@ -9,3 +9,5 @@ Either way, these boots have a few useful properties: as long as they have power
Additionally, due to always being in kind of a hovering state anyway, they allow you to seamlessly walk up steps of up to one block height. This is particularly handy when sprinting up a mountain, for example, a very commonplace fitness routine amongst Minecrafters. Or so I hear.
The boots can be recharged in an OpenComputers [charger](../block/charger.md) or any other such device, like the Applied Energistics 2 charger, an IndustrialCraft 2 battery box, or the Energetic Infuser from Thermal Expansion.
+
+You can change the boots' color by crafting them with any type of dye. Akin to leather armor, it is possible to apply multiple dyes at once or in succession to create a large variety of colors. The dye can be removed again either by crafting the boots with a bucket of water or by tossing them into a cauldron.
From 94721f03ea1053a71a8d96422938f5898fc0f260 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Wed, 24 Feb 2016 19:30:04 +0100
Subject: [PATCH 10/16] Super minor cleanup.
---
.../cil/oc/integration/thaumicenergistics/NetworkControl.scala | 1 -
.../thaumicenergistics/ThaumicEnergisticsUtils.scala | 3 +--
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
index 778cc648f..61a18b252 100644
--- a/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/NetworkControl.scala
@@ -2,7 +2,6 @@ package li.cil.oc.integration.thaumicenergistics
import appeng.api.networking.security.IActionHost
import appeng.me.helpers.IGridProxyable
-import extracells.api.ECApi
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
index aa9ee8f77..0f1079c8f 100644
--- a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
+++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ThaumicEnergisticsUtils.scala
@@ -2,9 +2,8 @@ package li.cil.oc.integration.thaumicenergistics
import appeng.api.storage.data.IAEFluidStack
-
object ThaumicEnergisticsUtils {
- def getAspect(fluid: IAEFluidStack) ={
+ def getAspect(fluid: IAEFluidStack) = {
val aspect = fluid.getFluidStack.copy()
aspect.amount = (fluid.getStackSize / 128).toInt
aspect
From 6c050032a3a3802bcc719c85d993951f1d682f6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Wed, 24 Feb 2016 19:59:35 +0100
Subject: [PATCH 11/16] Organize imports.
---
.../scala/li/cil/oc/common/item/HoverBoots.scala | 16 +++++++++++-----
.../li/cil/oc/common/recipe/ColorizeRecipe.scala | 6 ++++--
.../cil/oc/common/recipe/DecolorizeRecipe.scala | 3 ++-
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
index abc28fb90..73b58e6b7 100644
--- a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
+++ b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
@@ -1,6 +1,7 @@
package li.cil.oc.common.item
-import cpw.mods.fml.relauncher.{Side, SideOnly}
+import cpw.mods.fml.relauncher.Side
+import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.Settings
import li.cil.oc.client.renderer.item.HoverBootRenderer
import li.cil.oc.common.item.data.HoverBootsData
@@ -9,11 +10,16 @@ import net.minecraft.client.model.ModelBiped
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.EntityPlayer
-import net.minecraft.entity.{Entity, EntityLivingBase}
+import net.minecraft.entity.Entity
+import net.minecraft.entity.EntityLivingBase
import net.minecraft.init.Blocks
-import net.minecraft.item.{EnumRarity, ItemArmor, ItemStack}
-import net.minecraft.potion.{Potion, PotionEffect}
-import net.minecraft.util.{IIcon, MathHelper}
+import net.minecraft.item.EnumRarity
+import net.minecraft.item.ItemArmor
+import net.minecraft.item.ItemStack
+import net.minecraft.potion.Potion
+import net.minecraft.potion.PotionEffect
+import net.minecraft.util.IIcon
+import net.minecraft.util.MathHelper
import net.minecraft.world.World
class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with traits.SimpleItem with traits.Chargeable {
diff --git a/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
index 74a95919c..11fff1776 100644
--- a/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
@@ -1,10 +1,12 @@
package li.cil.oc.common.recipe
-import li.cil.oc.util.{Color, ItemColorizer}
+import li.cil.oc.util.Color
+import li.cil.oc.util.ItemColorizer
import net.minecraft.entity.passive.EntitySheep
import net.minecraft.inventory.InventoryCrafting
import net.minecraft.item.crafting.IRecipe
-import net.minecraft.item.{Item, ItemStack}
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
import net.minecraft.world.World
/**
diff --git a/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
index f6cdb547a..32b7620f4 100644
--- a/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala
@@ -4,7 +4,8 @@ import li.cil.oc.util.ItemColorizer
import net.minecraft.init.Items
import net.minecraft.inventory.InventoryCrafting
import net.minecraft.item.crafting.IRecipe
-import net.minecraft.item.{Item, ItemStack}
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
import net.minecraft.world.World
/**
From 49a0f8560c06a671382656a0ba04db2115772c92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Wed, 24 Feb 2016 20:21:36 +0100
Subject: [PATCH 12/16] Say no to sideonly fields!
---
src/main/scala/li/cil/oc/client/Textures.scala | 4 ++++
src/main/scala/li/cil/oc/common/item/HoverBoots.scala | 8 +++-----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/main/scala/li/cil/oc/client/Textures.scala b/src/main/scala/li/cil/oc/client/Textures.scala
index fdfffebb1..ff52404b5 100644
--- a/src/main/scala/li/cil/oc/client/Textures.scala
+++ b/src/main/scala/li/cil/oc/client/Textures.scala
@@ -92,6 +92,10 @@ object Textures {
var iconTopOn: IIcon = _
}
+ object HoverBoots {
+ var lightOverlay: IIcon = _
+ }
+
object PowerDistributor {
var iconSideOn: IIcon = _
var iconTopOn: IIcon = _
diff --git a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
index 73b58e6b7..49d1c47b5 100644
--- a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
+++ b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala
@@ -3,6 +3,7 @@ package li.cil.oc.common.item
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.Settings
+import li.cil.oc.client.Textures
import li.cil.oc.client.renderer.item.HoverBootRenderer
import li.cil.oc.common.item.data.HoverBootsData
import li.cil.oc.util.ItemColorizer
@@ -98,20 +99,17 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
super.onEntityItemUpdate(entity)
}
- @SideOnly(Side.CLIENT)
- var lightOverlay: IIcon = null
-
@SideOnly(Side.CLIENT)
override def registerIcons(ir: IIconRegister): Unit = {
this.itemIcon = ir.registerIcon(this.getIconString)
- this.lightOverlay = ir.registerIcon(this.getIconString + "Light")
+ Textures.HoverBoots.lightOverlay = ir.registerIcon(this.getIconString + "Light")
}
@SideOnly(Side.CLIENT)
override def requiresMultipleRenderPasses(): Boolean = true
@SideOnly(Side.CLIENT)
- override def getIconFromDamageForRenderPass(meta: Int, pass: Int): IIcon = if (pass == 1) lightOverlay else super.getIconFromDamageForRenderPass(meta, pass)
+ override def getIconFromDamageForRenderPass(meta: Int, pass: Int): IIcon = if (pass == 1) Textures.HoverBoots.lightOverlay else super.getIconFromDamageForRenderPass(meta, pass)
override def getColorFromItemStack(itemStack: ItemStack, pass: Int): Int = {
if (pass == 1) {
From 0613237fc6862cbd6d4e577dac01949c8446b76c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Wed, 24 Feb 2016 20:22:19 +0100
Subject: [PATCH 13/16] Cleanup.
---
.../cil/oc/client/renderer/PetRenderer.scala | 27 ++++++++-----------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
index c08b8eced..53b3d6977 100644
--- a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
+++ b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala
@@ -10,7 +10,6 @@ import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent
import li.cil.oc.api.event.RobotRenderEvent
import li.cil.oc.client.renderer.tileentity.RobotRenderer
import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.entity.Entity
import net.minecraftforge.client.event.RenderPlayerEvent
import org.lwjgl.opengl.GL11
@@ -26,16 +25,16 @@ object PetRenderer {
// http://goo.gl/frLWYR
private val entitledPlayers = Map(
- "9f1f262f-0d68-4e13-9161-9eeaf4a0a1a8" ->(0.3, 0.9, 0.6), //Sangar
- "18f8bed4-f027-44af-8947-6a3a2317645a" ->(1.0, 0.0, 0.0), //Jodarion
- "36123742-2cf6-4cfc-8b65-278581b3caeb" ->(0.5, 0.7, 1.0), //DaKaTotal
- "2c0c214b-96f4-4565-b513-de90d5fbc977" ->(1.0, 0.0, 0.0), //MichiRavencroft
- "f3ba6ec8-c280-4950-bb08-1fcb2eab3a9c" ->(0.18, 0.95, 0.922), //Vexatos
- "9d636bdd-b9f4-4b80-b9ce-586ca04bd4f3" ->(0.8, 0.77, 0.75), //StoneNomad
- "23c7ed71-fb13-4abe-abe7-f355e1de6e62" ->(0.3, 0.3, 1.0), //LizzyTheSiren
- "076541f1-f10a-46de-a127-dfab8adfbb75" ->(0.2, 1.0, 0.1), //vifino
- "e7e90198-0ccf-4662-a827-192ec8f4419d" ->(0.0, 0.2, 0.6), //Izaya
- "f514ee69-7bbb-4e46-9e94-d8176324cec2" ->(0.098, 0.471, 0.784) //Wobbo
+ "9f1f262f-0d68-4e13-9161-9eeaf4a0a1a8" ->(0.3, 0.9, 0.6), // Sangar
+ "18f8bed4-f027-44af-8947-6a3a2317645a" ->(1.0, 0.0, 0.0), // Jodarion
+ "36123742-2cf6-4cfc-8b65-278581b3caeb" ->(0.5, 0.7, 1.0), // DaKaTotal
+ "2c0c214b-96f4-4565-b513-de90d5fbc977" ->(1.0, 0.0, 0.0), // MichiRavencroft
+ "f3ba6ec8-c280-4950-bb08-1fcb2eab3a9c" ->(0.18, 0.95, 0.922), // Vexatos
+ "9d636bdd-b9f4-4b80-b9ce-586ca04bd4f3" ->(0.8, 0.77, 0.75), // StoneNomad
+ "23c7ed71-fb13-4abe-abe7-f355e1de6e62" ->(0.3, 0.3, 1.0), // LizzyTheSiren
+ "076541f1-f10a-46de-a127-dfab8adfbb75" ->(0.2, 1.0, 0.1), // vifino
+ "e7e90198-0ccf-4662-a827-192ec8f4419d" ->(0.0, 0.2, 0.6), // Izaya
+ "f514ee69-7bbb-4e46-9e94-d8176324cec2" ->(0.098, 0.471, 0.784) // Wobbo
)
private val petLocations = com.google.common.cache.CacheBuilder.newBuilder().
@@ -143,11 +142,7 @@ object PetRenderer {
GL11.glTranslated(0.3, -0.1, -0.2)
}
- //Sangar: Someone please tell me a cleaner solution than this...
- //tim4242: This seems to be cleaner, but what do I know?
- private def isForInventory = Minecraft.getMinecraft.currentScreen != null && owner == Minecraft.getMinecraft.thePlayer //Check if the player is currently in an inventory
- //private def isForInventory = new Exception().getStackTrace.exists(_.getClassName == classOf[GuiContainer].getName)
-
+ private def isForInventory = Minecraft.getMinecraft.currentScreen != null && owner == Minecraft.getMinecraft.thePlayer
}
@SubscribeEvent
From df269a5bbe198623476a9f0344bb838329b656da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Sat, 27 Feb 2016 11:01:24 +0100
Subject: [PATCH 14/16] Added `driver.SidedBlock` interface, deprecated old
`driver.Block` interface, closes #1650. Made CompoundBlockDriver support both
kinds.
---
src/main/java/li/cil/oc/api/Driver.java | 47 +++++++++++-
.../java/li/cil/oc/api/detail/DriverAPI.java | 39 ++++++++++
src/main/java/li/cil/oc/api/driver/Block.java | 4 +
.../java/li/cil/oc/api/driver/SidedBlock.java | 74 +++++++++++++++++++
.../server/driver/CompoundBlockDriver.scala | 19 +++--
.../driver/CompoundBlockEnvironment.scala | 16 ++--
.../li/cil/oc/server/driver/Registry.scala | 32 +++++++-
7 files changed, 211 insertions(+), 20 deletions(-)
create mode 100644 src/main/java/li/cil/oc/api/driver/SidedBlock.java
diff --git a/src/main/java/li/cil/oc/api/Driver.java b/src/main/java/li/cil/oc/api/Driver.java
index 57b194e26..e805b65ee 100644
--- a/src/main/java/li/cil/oc/api/Driver.java
+++ b/src/main/java/li/cil/oc/api/Driver.java
@@ -5,11 +5,13 @@ import li.cil.oc.api.driver.Converter;
import li.cil.oc.api.driver.EnvironmentProvider;
import li.cil.oc.api.driver.InventoryProvider;
import li.cil.oc.api.driver.Item;
+import li.cil.oc.api.driver.SidedBlock;
import li.cil.oc.api.network.EnvironmentHost;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
import java.util.Collection;
@@ -27,7 +29,7 @@ import java.util.Collection;
* at that time. Only start calling these methods in the init phase or later.
*
* @see Network
- * @see Block
+ * @see SidedBlock
* @see Item
*/
public final class Driver {
@@ -42,12 +44,31 @@ public final class Driver {
* phases.
*
* @param driver the driver to register.
+ * @deprecated Use {@link SidedBlock} instead.
*/
+ @Deprecated // TODO Remove in OC 1.7
public static void add(final Block driver) {
if (API.driver != null)
API.driver.add(driver);
}
+ /**
+ * Registers a new side-aware block driver.
+ *
+ * Whenever the neighboring blocks of an Adapter block change, it checks if
+ * there exists a driver for the changed block, and if it is configured to
+ * interface that block type connects it to the component network.
+ *
+ * This must be called in the init phase, not the pre- or post-init
+ * phases.
+ *
+ * @param driver the driver to register.
+ */
+ public static void add(final SidedBlock driver) {
+ if (API.driver != null)
+ API.driver.add(driver);
+ }
+
/**
* Registers a new item driver.
*
@@ -122,13 +143,37 @@ public final class Driver {
* @param y the Y coordinate of the block.
* @param z the Z coordinate of the block.
* @return a driver for the block, or null if there is none.
+ * @deprecated Use {@link #driverFor(World, int, int, int, ForgeDirection)},
+ * passing UNKNOWN if the side is to be ignored.
*/
+ @Deprecated // TODO Remove in OC 1.7
public static Block driverFor(World world, int x, int y, int z) {
if (API.driver != null)
return API.driver.driverFor(world, x, y, z);
return null;
}
+ /**
+ * Looks up a driver for the block at the specified position in the
+ * specified world.
+ *
+ * Note that several drivers for a single block can exist. Because of this
+ * block drivers are always encapsulated in a 'compound' driver, which is
+ * what will be returned here. In other words, you should will not
+ * get actual instances of drivers registered via {@link #add(li.cil.oc.api.driver.Block)}.
+ *
+ * @param world the world containing the block.
+ * @param x the X coordinate of the block.
+ * @param y the Y coordinate of the block.
+ * @param z the Z coordinate of the block.
+ * @return a driver for the block, or null if there is none.
+ */
+ public static SidedBlock driverFor(World world, int x, int y, int z, ForgeDirection side) {
+ if (API.driver != null)
+ return API.driver.driverFor(world, x, y, z, side);
+ return null;
+ }
+
/**
* Looks up a driver for the specified item stack.
*
diff --git a/src/main/java/li/cil/oc/api/detail/DriverAPI.java b/src/main/java/li/cil/oc/api/detail/DriverAPI.java
index 921453e19..8c1d1b4f7 100644
--- a/src/main/java/li/cil/oc/api/detail/DriverAPI.java
+++ b/src/main/java/li/cil/oc/api/detail/DriverAPI.java
@@ -5,11 +5,13 @@ import li.cil.oc.api.driver.Converter;
import li.cil.oc.api.driver.EnvironmentProvider;
import li.cil.oc.api.driver.InventoryProvider;
import li.cil.oc.api.driver.Item;
+import li.cil.oc.api.driver.SidedBlock;
import li.cil.oc.api.network.EnvironmentHost;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
import java.util.Collection;
@@ -25,9 +27,25 @@ public interface DriverAPI {
* phases.
*
* @param driver the driver for a block component.
+ * @deprecated Use {@link SidedBlock} instead.
*/
+ @Deprecated // TODO Remove in OC 1.7
void add(Block driver);
+ /**
+ * Registers a new side-aware block driver.
+ *
+ * Whenever the neighboring blocks of an Adapter block change, it checks if
+ * there exists a driver for the changed block, and if it is configured to
+ * interface that block type connects it to the component network.
+ *
+ * This must be called in the init phase, not the pre- or post-init
+ * phases.
+ *
+ * @param driver the driver to register.
+ */
+ void add(SidedBlock driver);
+
/**
* Registers a new driver for an item component.
*
@@ -90,9 +108,30 @@ public interface DriverAPI {
* @param y the Y coordinate of the block.
* @param z the Z coordinate of the block.
* @return a driver for the block, or null if there is none.
+ * @deprecated Use {@link #driverFor(World, int, int, int, ForgeDirection)},
+ * passing UNKNOWN if the side is to be ignored.
*/
+ @Deprecated // TODO Remove in OC 1.7
Block driverFor(World world, int x, int y, int z);
+ /**
+ * Looks up a driver for the block at the specified position in the
+ * specified world.
+ *
+ * Note that several drivers for a single block can exist. Because of this
+ * block drivers are always encapsulated in a 'compound' driver, which is
+ * what will be returned here. In other words, you should will not
+ * get actual instances of drivers registered via {@link #add(li.cil.oc.api.driver.Block)}.
+ *
+ * @param world the world containing the block.
+ * @param x the X coordinate of the block.
+ * @param y the Y coordinate of the block.
+ * @param z the Z coordinate of the block.
+ * @param side the side of the block.
+ * @return a driver for the block, or null if there is none.
+ */
+ SidedBlock driverFor(World world, int x, int y, int z, ForgeDirection side);
+
/**
* Looks up a driver for the specified item stack.
*
diff --git a/src/main/java/li/cil/oc/api/driver/Block.java b/src/main/java/li/cil/oc/api/driver/Block.java
index 895a629bf..d6ac81dd2 100644
--- a/src/main/java/li/cil/oc/api/driver/Block.java
+++ b/src/main/java/li/cil/oc/api/driver/Block.java
@@ -20,7 +20,11 @@ import net.minecraft.world.World;
* Note that it is possible to write one driver that supports as many different
* blocks as you wish. I'd recommend writing one per device (type), though, to
* keep things modular.
+ *
+ * @deprecated Use {@link SidedBlock} instead, ignoring the side argument if
+ * the side doesn't matter.
*/
+@Deprecated // TODO Remove in OC 1.7
public interface Block {
/**
* Used to determine the block types this driver handles.
diff --git a/src/main/java/li/cil/oc/api/driver/SidedBlock.java b/src/main/java/li/cil/oc/api/driver/SidedBlock.java
new file mode 100644
index 000000000..8cf92e216
--- /dev/null
+++ b/src/main/java/li/cil/oc/api/driver/SidedBlock.java
@@ -0,0 +1,74 @@
+package li.cil.oc.api.driver;
+
+import li.cil.oc.api.network.ManagedEnvironment;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+/**
+ * Interface for side-aware block component drivers.
+ *
+ * This driver type is used for components that are blocks, i.e. that can be
+ * placed in the world, but cannot be modified to or don't want to have their
+ * {@link net.minecraft.tileentity.TileEntity} implement one of the interfaces
+ * for environments ({@link li.cil.oc.api.network.Environment} or
+ * {@link li.cil.oc.api.network.SidedEnvironment}).
+ *
+ * A block driver is used by Adapter blocks to check its neighbors and
+ * whether those neighbors should be treated as components or not. If a driver
+ * is present, it will be used to create a {@link ManagedEnvironment} that is
+ * managed by the adapter.
+ *
+ * Note that it is possible to write one driver that supports as many different
+ * blocks as you wish. I'd recommend writing one per device (type), though, to
+ * keep things modular.
+ *
+ * Note that side-aware block drivers are queried before regular block drivers,
+ * because they are more specific.
+ */
+public interface SidedBlock {
+ /**
+ * Used to determine the block types this driver handles.
+ *
+ * This is used to determine which driver to use for a block placed next to
+ * an Adapter block. Note that the return value should not change
+ * over time; if it does, though, an already installed component will not
+ * be removed, since this value is only checked when scanning blocks. You
+ * can force this by sending a neighbor block change notification.
+ *
+ * The side is relative to the block, i.e. "south" is the side of the block
+ * facing south.
+ *
+ * @param world the world in which the block to check lives.
+ * @param x the X coordinate of the block to check.
+ * @param y the Y coordinate of the block to check.
+ * @param z the Z coordinate of the block to check.
+ * @param side the side of the block to check.
+ * @return true if the block is supported; false otherwise.
+ */
+ boolean worksWith(World world, int x, int y, int z, ForgeDirection side);
+
+ /**
+ * Create a new managed environment interfacing the specified block.
+ *
+ * This is used to connect the component to the component network when it
+ * is detected next to an Adapter. Components that are not part of
+ * the component network probably don't make much sense (can't think of any
+ * uses at this time), but you may still opt to not implement this - i.e.
+ * it is safe to return null here.
+ *
+ * This is expected to return a new instance each time it is
+ * called. The created instance's life cycle is managed by the
+ * Adapter block that caused its creation.
+ *
+ * The side is relative to the block, i.e. "south" is the side of the block
+ * facing south.
+ *
+ * @param world the world containing the block to get the environment for.
+ * @param x the X coordinate of the block to get the environment for.
+ * @param y the Y coordinate of the block to get the environment for.
+ * @param z the Z coordinate of the block to get the environment for.
+ * @param side the side of the block to check.
+ * @return the environment for the block at that location.
+ */
+ ManagedEnvironment createEnvironment(World world, int x, int y, int z, ForgeDirection side);
+}
\ No newline at end of file
diff --git a/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala b/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala
index 182daea6b..8aa470b48 100644
--- a/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala
+++ b/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala
@@ -9,12 +9,19 @@ import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.tileentity.TileEntity
import net.minecraft.world.World
+import net.minecraftforge.common.util.ForgeDirection
-class CompoundBlockDriver(val blocks: driver.Block*) extends driver.Block {
- override def createEnvironment(world: World, x: Int, y: Int, z: Int) = {
- val list = blocks.map {
+// TODO Remove blocks in OC 1.7.
+class CompoundBlockDriver(val sidedBlocks: Array[driver.SidedBlock], val blocks: Array[driver.Block]) extends driver.SidedBlock {
+ override def createEnvironment(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = {
+ val list = sidedBlocks.map {
+ driver => Option(driver.createEnvironment(world, x, y, z, side)) match {
+ case Some(environment) => (driver.getClass.getName, environment)
+ case _ => null
+ }
+ } ++ blocks.map {
driver => Option(driver.createEnvironment(world, x, y, z)) match {
- case Some(environment) => (driver, environment)
+ case Some(environment) => (driver.getClass.getName, environment)
case _ => null
}
} filter (_ != null)
@@ -22,10 +29,10 @@ class CompoundBlockDriver(val blocks: driver.Block*) extends driver.Block {
else new CompoundBlockEnvironment(cleanName(tryGetName(world, x, y, z, list.map(_._2))), list: _*)
}
- override def worksWith(world: World, x: Int, y: Int, z: Int) = blocks.forall(_.worksWith(world, x, y, z))
+ override def worksWith(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = sidedBlocks.forall(_.worksWith(world, x, y, z, side)) && blocks.forall(_.worksWith(world, x, y, z))
override def equals(obj: Any) = obj match {
- case multi: CompoundBlockDriver if multi.blocks.length == blocks.length => blocks.intersect(multi.blocks).length == blocks.length
+ case multi: CompoundBlockDriver if multi.sidedBlocks.length == sidedBlocks.length && multi.blocks.length == blocks.length => sidedBlocks.intersect(multi.sidedBlocks).length == sidedBlocks.length && blocks.intersect(multi.blocks).length == blocks.length
case _ => false
}
diff --git a/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala b/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala
index c45a5846f..09bad3df2 100644
--- a/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala
+++ b/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala
@@ -5,12 +5,12 @@ import java.nio.charset.Charset
import com.google.common.hash.Hashing
import li.cil.oc.OpenComputers
import li.cil.oc.api
-import li.cil.oc.api.driver
import li.cil.oc.api.network._
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.nbt.NBTTagCompound
-class CompoundBlockEnvironment(val name: String, val environments: (driver.Block, ManagedEnvironment)*) extends ManagedEnvironment {
+// TODO Remove block in OC 1.7.
+class CompoundBlockEnvironment(val name: String, val environments: (String, ManagedEnvironment)*) extends ManagedEnvironment {
// Block drivers with visibility < network usually won't make much sense,
// but let's play it safe and use the least possible visibility based on
// the drivers we encapsulate.
@@ -58,12 +58,11 @@ class CompoundBlockEnvironment(val name: String, val environments: (driver.Block
if (nbt.hasKey("typeHash") && nbt.getLong("typeHash") != typeHash) return
node.load(nbt)
for ((driver, environment) <- environments) {
- val name = driver.getClass.getName
- if (nbt.hasKey(name)) {
+ if (nbt.hasKey(driver)) {
try {
- environment.load(nbt.getCompoundTag(name))
+ environment.load(nbt.getCompoundTag(driver))
} catch {
- case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$name') threw an error while loading.", e)
+ case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while loading.", e)
}
}
}
@@ -73,11 +72,10 @@ class CompoundBlockEnvironment(val name: String, val environments: (driver.Block
nbt.setLong("typeHash", typeHash)
node.save(nbt)
for ((driver, environment) <- environments) {
- val name = driver.getClass.getName
try {
- nbt.setNewCompoundTag(name, environment.save)
+ nbt.setNewCompoundTag(driver, environment.save)
} catch {
- case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$name') threw an error while saving.", e)
+ case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while saving.", e)
}
}
}
diff --git a/src/main/scala/li/cil/oc/server/driver/Registry.scala b/src/main/scala/li/cil/oc/server/driver/Registry.scala
index 3a1d54482..c787f4106 100644
--- a/src/main/scala/li/cil/oc/server/driver/Registry.scala
+++ b/src/main/scala/li/cil/oc/server/driver/Registry.scala
@@ -10,10 +10,12 @@ import li.cil.oc.api.driver.InventoryProvider
import li.cil.oc.api.driver.item.HostAware
import li.cil.oc.api.machine.Value
import li.cil.oc.api.network.EnvironmentHost
+import li.cil.oc.api.network.ManagedEnvironment
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
import net.minecraft.world.World
+import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._
@@ -37,6 +39,8 @@ import scala.math.ScalaNumber
private[oc] object Registry extends api.detail.DriverAPI {
val blocks = mutable.ArrayBuffer.empty[api.driver.Block]
+ val sidedBlocks = mutable.ArrayBuffer.empty[api.driver.SidedBlock]
+
val items = mutable.ArrayBuffer.empty[api.driver.Item]
val converters = mutable.ArrayBuffer.empty[api.driver.Converter]
@@ -58,9 +62,17 @@ private[oc] object Registry extends api.detail.DriverAPI {
}
}
+ override def add(driver: api.driver.SidedBlock) {
+ if (locked) throw new IllegalStateException("Please register all drivers in the init phase.")
+ if (!sidedBlocks.contains(driver)) {
+ OpenComputers.log.debug(s"Registering block driver ${driver.getClass.getName}.")
+ sidedBlocks += driver
+ }
+ }
+
override def add(driver: api.driver.Item) {
if (locked) throw new IllegalStateException("Please register all drivers in the init phase.")
- if (!blocks.contains(driver)) {
+ if (!items.contains(driver)) {
OpenComputers.log.debug(s"Registering item driver ${driver.getClass.getName}.")
items += driver
}
@@ -90,9 +102,21 @@ private[oc] object Registry extends api.detail.DriverAPI {
}
}
- override def driverFor(world: World, x: Int, y: Int, z: Int) =
- blocks.filter(_.worksWith(world, x, y, z)) match {
- case drivers if drivers.nonEmpty => new CompoundBlockDriver(drivers: _*)
+ // TODO Remove in OC 1.7
+ override def driverFor(world: World, x: Int, y: Int, z: Int) = {
+ driverFor(world, x, y, z, ForgeDirection.UNKNOWN) match {
+ case driver: api.driver.SidedBlock => new api.driver.Block {
+ override def worksWith(world: World, x: Int, y: Int, z: Int): Boolean = driver.worksWith(world, x, y, z, ForgeDirection.UNKNOWN)
+
+ override def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment = driver.createEnvironment(world, x, y, z, ForgeDirection.UNKNOWN)
+ }
+ case _ => null
+ }
+ }
+
+ override def driverFor(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) =
+ (sidedBlocks.filter(_.worksWith(world, x, y, z, side)), blocks.filter(_.worksWith(world, x, y, z))) match {
+ case (sidedDrivers, drivers) if sidedDrivers.nonEmpty || drivers.nonEmpty => new CompoundBlockDriver(sidedDrivers.toArray, drivers.toArray)
case _ => null
}
From 13cff88dc1c9539008ed893a4cbe97f3e0e320aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Sat, 27 Feb 2016 11:29:57 +0100
Subject: [PATCH 15/16] Fixed recipe sorting.
---
src/main/scala/li/cil/oc/common/recipe/Recipes.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
index 2a6e986be..040aebd30 100644
--- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
+++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala
@@ -90,7 +90,7 @@ object Recipes {
RecipeSorter.register(Settings.namespace + "extshaped", classOf[ExtendedShapedOreRecipe], Category.SHAPED, "after:forge:shapedore")
RecipeSorter.register(Settings.namespace + "extshapeless", classOf[ExtendedShapelessOreRecipe], Category.SHAPELESS, "after:forge:shapelessore")
RecipeSorter.register(Settings.namespace + "colorizer", classOf[ColorizeRecipe], Category.SHAPELESS, "after:forge:shapelessore")
- RecipeSorter.register(Settings.namespace + "decolorizer", classOf[DecolorizeRecipe], Category.SHAPELESS, "after:oc:decolorizer")
+ RecipeSorter.register(Settings.namespace + "decolorizer", classOf[DecolorizeRecipe], Category.SHAPELESS, "after:oc:colorizer")
for ((name, stack) <- oreDictEntries) {
if (!OreDictionary.getOres(name).contains(stack)) {
From 44e771cb7587a851c32438be7163efcd97bbb931 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20N=C3=BCcke?=
Date: Sat, 27 Feb 2016 11:33:12 +0100
Subject: [PATCH 16/16] Limit max number of items crafted in one command to one
stack, closes #1651. Prevents semi-infinite loops for identity-crafting (i.e.
input == output).
---
src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala b/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala
index cd97d60be..e19c5f8a1 100644
--- a/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala
+++ b/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala
@@ -27,7 +27,7 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
@Callback(doc = """function([count:number]):number -- Tries to craft the specified number of items in the top left area of the inventory.""")
def craft(context: Context, args: Arguments): Array[AnyRef] = {
- val count = args.optInteger(0, Int.MaxValue)
+ val count = args.optInteger(0, 64) max 0 min 64
result(CraftingInventory.craft(count): _*)
}