diff --git a/assets/items.psd b/assets/items.psd index 4b5a90b2a..111d91668 100644 Binary files a/assets/items.psd and b/assets/items.psd differ diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua index 13967684e..7d18bd210 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/kernel.lua @@ -348,7 +348,9 @@ function wrapSingleUserdata(data) -- without the need of metamethods like __eq, as well as proper reference -- behavior after saving and loading again. for k, v in pairs(wrappedUserdata) do - if v == data then + -- We need a custom 'equals' check for userdata because metamethods on + -- userdata introduced by JNLua tend to crash the game for some reason. + if userdata.equal(v, data) then return k end end diff --git a/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png b/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png index c6aa08cca..40d15fa4e 100644 Binary files a/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png and b/src/main/resources/assets/opencomputers/textures/items/disk_floppy.png differ diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index cf9adb1a2..0f8cccb5a 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -6,7 +6,7 @@ import cpw.mods.fml.common.network.NetworkRegistry import cpw.mods.fml.common.registry.TickRegistry import cpw.mods.fml.relauncher.Side import li.cil.oc.client.renderer.block.BlockRenderer -import li.cil.oc.client.renderer.item.UpgradeRenderer +import li.cil.oc.client.renderer.item.{FloppyRenderer, UpgradeRenderer} import li.cil.oc.client.renderer.tileentity._ import li.cil.oc.client.renderer.{TextBufferRenderCache, WirelessNetworkDebugRenderer} import li.cil.oc.common.{Proxy => CommonProxy, tileentity} @@ -46,6 +46,7 @@ private[oc] class Proxy extends CommonProxy { ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer) MinecraftForgeClient.registerItemRenderer(Items.multi.itemID, UpgradeRenderer) + MinecraftForgeClient.registerItemRenderer(Items.multi.itemID, FloppyRenderer) MinecraftForge.EVENT_BUS.register(gui.Icons) diff --git a/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala new file mode 100644 index 000000000..8fdc379c1 --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/item/FloppyRenderer.scala @@ -0,0 +1,50 @@ +package li.cil.oc.client.renderer.item + +import li.cil.oc.{Settings, api} +import net.minecraftforge.client.IItemRenderer +import net.minecraftforge.client.IItemRenderer.{ItemRendererHelper, ItemRenderType} +import net.minecraft.item.ItemStack +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.entity.{RenderItem, RenderManager} +import net.minecraft.client.gui.ScaledResolution +import org.lwjgl.opengl.GL11 +import scala.collection.convert.WrapAsScala._ +import net.minecraft.util.EnumChatFormatting + +object FloppyRenderer extends IItemRenderer { + val renderItem = new RenderItem() + renderItem.setRenderManager(RenderManager.instance) + + override def handleRenderType(stack: ItemStack, renderType: ItemRenderType) = renderType == ItemRenderType.INVENTORY && { + val descriptor = api.Items.get(stack) + descriptor == api.Items.get("floppy") || + descriptor == api.Items.get("lootDisk") || + descriptor == api.Items.get("openOS") + } + + override def shouldUseRenderHelper(renderType: ItemRenderType, stack: ItemStack, helper: ItemRendererHelper) = false + + override def renderItem(renderType: ItemRenderType, stack: ItemStack, data: AnyRef*) { + val mc = Minecraft.getMinecraft + renderItem.renderItemIntoGUI(null, mc.getTextureManager, stack, 0, 0) + val res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight) + val fontRenderer = renderItem.getFontRendererFromRenderManager + if (fontRenderer != null && res.getScaleFactor > 1) { + GL11.glPushMatrix() + GL11.glTranslatef(4f + 2f / res.getScaleFactor, 9f + 2f / res.getScaleFactor, 0) + GL11.glScalef(1f / res.getScaleFactor, 1f / res.getScaleFactor, 1f) + val maxLength = (res.getScaleFactor * 7.5).toInt + val label = + if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data") && stack.getTagCompound.getCompoundTag(Settings.namespace + "data").hasKey(Settings.namespace + "fs.label")) { + stack.getTagCompound.getCompoundTag(Settings.namespace + "data").getString(Settings.namespace + "fs.label") + } + else "disk" + val lines = fontRenderer.listFormattedStringToWidth(EnumChatFormatting.func_110646_a(label), maxLength).take(math.max(1, res.getScaleFactor / 2)) + for (line <- lines) { + fontRenderer.drawString(line.asInstanceOf[String], 0, 0, 0) + GL11.glTranslatef(0, fontRenderer.FONT_HEIGHT, 0) + } + GL11.glPopMatrix() + } + } +} diff --git a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala index 331f5cfab..8ca235fef 100644 --- a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala @@ -13,7 +13,7 @@ import org.lwjgl.opengl.GL11 object UpgradeRenderer extends IItemRenderer { val bounds = AxisAlignedBB.getBoundingBox(-0.1, -0.1, -0.1, 0.1, 0.1, 0.1) - + override def handleRenderType(stack: ItemStack, renderType: ItemRenderType) = renderType == ItemRenderType.EQUIPPED && { val descriptor = api.Items.get(stack) descriptor == api.Items.get("craftingUpgrade") || diff --git a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala index 4f02c46e9..ded56c816 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala @@ -241,7 +241,7 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu else { assert(lua.isThread(1)) // We're expecting the result of a pcall, if anything, so boolean + (result | string). - if (!lua.isBoolean(2) || !(lua.isString(3) || lua.isNil(3))) { + if (!lua.isBoolean(2) || !(lua.isString(3) || lua.isNoneOrNil(3))) { OpenComputers.log.warning("Kernel returned unexpected results.") } // The pcall *should* never return normally... but check for it nonetheless. @@ -251,7 +251,9 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu } else { lua.setTotalMemory(Int.MaxValue) - val error = lua.toString(3) + val error = + if (lua.isJavaObjectRaw(3)) lua.toJavaObjectRaw(3).toString + else lua.toString(3) if (error != null) new ExecutionResult.Error(error) else new ExecutionResult.Error("unknown error") } diff --git a/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala index 2867dc88f..22f24bf92 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/luac/UserdataAPI.scala @@ -103,6 +103,14 @@ class UserdataAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { }) lua.setField(-2, "doc") + lua.pushScalaFunction(lua => { + val value1 = lua.toJavaObjectRaw(1) + val value2 = lua.toJavaObjectRaw(2) + lua.pushBoolean(value1.isInstanceOf[Value] && value2.isInstanceOf[Value] && value1 == value2) + 1 + }) + lua.setField(-2, "equal") + lua.setGlobal("userdata") } } diff --git a/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala index 297be171b..11a816b84 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/luaj/UserdataAPI.scala @@ -59,6 +59,12 @@ class UserdataAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { owner.documentation(() => machine.documentation(value, method)) }) + userdata.set("equal", (args: Varargs) => { + val value1 = args.checkuserdata(1, classOf[Value]) + val value2 = args.checkuserdata(2, classOf[Value]) + LuaValue.valueOf(value1.isInstanceOf[Value] && value2.isInstanceOf[Value] && value1 == value2) + }) + lua.set("userdata", userdata) } }