diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 238f1d85f..af4f3558a 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -174,6 +174,8 @@ oc:gui.Chat.WarningPower=No supported power providing mod available. Computers, oc:gui.Chat.TextureName=§7Texture name is §a%s§f. oc:gui.Chat.WarningProjectRed=You are using a version of Project: Red that is incompatible with OpenComputers. Try updating your version of Project: Red. oc:gui.Chat.WarningRecipes=There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information. +oc:gui.Chat.WarningClassTransformer=There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you! +oc:gui.Chat.WarningSimpleComponent=An addon (yours?) using the §aSimpleComponent§f interface did §esomething wrong§f. Component logic could not be injected. Please check your log file for more information. oc:gui.Error.ComponentOverflow=Too many components connected to the computer. oc:gui.Error.InternalError=Internal error, please see the log file. This is probably a bug. oc:gui.Error.NoCPU=No CPU is installed in the computer. @@ -225,6 +227,7 @@ oc:tooltip.Adapter=Used to control non-component blocks, such as vanilla blocks oc:tooltip.ALU=Adds numbers so you don't have to. It might be better this way. oc:tooltip.Analyzer=Used to display information about blocks, such as their §faddress§7 and §fcomponent name§7.[nl] Also displays the error that caused a computer to crash if it did not shut down normally. oc:tooltip.Assembler=Allows constructing robots and other devices from a number of different computer parts. +oc:tooltip.BeaconBase=§8Works as a beacon base. oc:tooltip.Cable=A cheap way of connecting blocks. oc:tooltip.Capacitor=Stores energy for later use. Can be filled and emptied very quickly. oc:tooltip.CardBase=As the name indicates, this is the basic building block for all expansion cards. diff --git a/src/main/scala/li/cil/oc/Localization.scala b/src/main/scala/li/cil/oc/Localization.scala index 754a930fd..846cd47a6 100644 --- a/src/main/scala/li/cil/oc/Localization.scala +++ b/src/main/scala/li/cil/oc/Localization.scala @@ -85,6 +85,10 @@ object Localization { def WarningRecipes = new ChatComponentText("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningRecipes")) + def WarningClassTransformer = new ChatComponentText("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningClassTransformer")) + + def WarningSimpleComponent = new ChatComponentText("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningSimpleComponent")) + def InfoNewVersion(version: String) = new ChatComponentText("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.NewVersion", version)) def TextureName(name: String) = new ChatComponentText("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.TextureName", name)) @@ -140,6 +144,8 @@ object Localization { def Materials = localizeImmediately("tooltip.Materials") def Tier(tier: Int) = localizeImmediately("tooltip.Tier", tier.toString) + + def BeaconBase = localizeImmediately("tooltip.BeaconBase") } } diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index e115773d5..ea38c731c 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -14,6 +14,7 @@ import li.cil.oc.api.Network import li.cil.oc.api.detail.ItemInfo import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.{PacketSender => ClientPacketSender} +import li.cil.oc.common.asm.ClassTransformer import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.TabletData @@ -160,6 +161,12 @@ object EventHandler { if (Recipes.hadErrors) { player.addChatMessage(Localization.Chat.WarningRecipes) } + if (ClassTransformer.hadErrors) { + player.addChatMessage(Localization.Chat.WarningClassTransformer) + } + if (ClassTransformer.hadSimpleComponentErrors) { + player.addChatMessage(Localization.Chat.WarningSimpleComponent) + } ServerPacketSender.sendPetVisibility(None, Some(player)) // Do update check in local games and for OPs. if (!Mods.VersionChecker.isAvailable && (!MinecraftServer.getServer.isDedicatedServer || MinecraftServer.getServer.getConfigurationManager.func_152596_g(player.getGameProfile))) { diff --git a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala b/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala index 6561ec357..fb8235ec8 100644 --- a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala +++ b/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala @@ -33,9 +33,13 @@ object ObfNames { final val Method_writeToNBT = Array("writeToNBT", "func_145841_b") } +object ClassTransformer { + var hadErrors = false + var hadSimpleComponentErrors = false +} + class ClassTransformer extends IClassTransformer { private val loader = classOf[ClassTransformer].getClassLoader.asInstanceOf[LaunchClassLoader] - private val log = LogManager.getLogger("OpenComputers") override def transform(name: String, transformedName: String, basicClass: Array[Byte]): Array[Byte] = { @@ -73,7 +77,7 @@ class ClassTransformer extends IClassTransformer { // Inject available interfaces where requested. if (classNode.visibleAnnotations != null) { def injectInterface(annotation: AnnotationNode): Unit = { - val values = annotation.values.grouped(2).map(buffer => buffer(0) -> buffer(1)).toMap + val values = annotation.values.grouped(2).map(buffer => buffer.head -> buffer.last).toMap (values.get("value"), values.get("modid")) match { case (Some(interfaceName: String), Some(modid: String)) => Mods.All.find(_.id == modid) match { @@ -93,6 +97,7 @@ class ClassTransformer extends IClassTransformer { else { log.warn(s"Missing implementations for interface $interfaceName, skipping injection.") missing.foreach(log.warn) + ClassTransformer.hadErrors = true } } } @@ -113,7 +118,7 @@ class ClassTransformer extends IClassTransformer { } classNode.visibleAnnotations.find(_.desc == "Lli/cil/oc/common/asm/Injectable$InterfaceList;") match { case Some(annotation) => - val values = annotation.values.grouped(2).map(buffer => buffer(0) -> buffer(1)).toMap + val values = annotation.values.grouped(2).map(buffer => buffer.head -> buffer.last).toMap values.get("value") match { case Some(interfaceList: java.lang.Iterable[AnnotationNode]@unchecked) => interfaceList.foreach(injectInterface) @@ -135,6 +140,7 @@ class ClassTransformer extends IClassTransformer { catch { case e: Throwable => log.warn(s"Failed injecting component logic into class $name.", e) + ClassTransformer.hadSimpleComponentErrors = true } } } @@ -220,6 +226,7 @@ class ClassTransformer extends IClassTransformer { catch { case t: Throwable => log.warn("Something went wrong!", t) + ClassTransformer.hadErrors = true basicClass } } @@ -233,10 +240,12 @@ class ClassTransformer extends IClassTransformer { } else { log.warn(s"Failed patching ${classNode.name}.${methodNames(0)}, injection point not found.") + ClassTransformer.hadErrors = true None } case _ => log.warn(s"Failed patching ${classNode.name}.${methodNames(0)}, method not found.") + ClassTransformer.hadErrors = true None } } diff --git a/src/main/scala/li/cil/oc/common/block/Print.scala b/src/main/scala/li/cil/oc/common/block/Print.scala index 6e8e4491f..4f65738a0 100644 --- a/src/main/scala/li/cil/oc/common/block/Print.scala +++ b/src/main/scala/li/cil/oc/common/block/Print.scala @@ -5,6 +5,7 @@ import java.util.Random import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.tileentity @@ -49,6 +50,9 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends override protected def tooltipBody(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean): Unit = { super.tooltipBody(metadata, stack, player, tooltip, advanced) val data = new PrintData(stack) + if (data.isBeaconBase) { + tooltip.add(Localization.Tooltip.BeaconBase) + } data.tooltip.foreach(s => tooltip.addAll(s.lines.toIterable)) } diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index d656918a6..e6ac8bdd1 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -370,11 +370,6 @@ object Items extends ItemAPI { // v1.2.3 registerItem(new item.FloppyDisk(multi) { showInItemList = false - - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { - if (player.isSneaking) get("floppy").createItemStack(1) - else super.onItemRightClick(stack, world, player) - } }, "lootDisk") // v1.2.6 diff --git a/src/main/scala/li/cil/oc/common/item/Delegate.scala b/src/main/scala/li/cil/oc/common/item/Delegate.scala index 95f45035c..d50e5e7fa 100644 --- a/src/main/scala/li/cil/oc/common/item/Delegate.scala +++ b/src/main/scala/li/cil/oc/common/item/Delegate.scala @@ -46,15 +46,7 @@ trait Delegate { def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = false - def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = { - if (player.isSneaking) { - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) { - stack.setTagCompound(null) - player.swingItem() - } - } - stack - } + def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = stack def getItemUseAction(stack: ItemStack): EnumAction = EnumAction.none diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala index cd58408a1..8eb8686e7 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala @@ -16,6 +16,7 @@ import li.cil.oc.util.SideTracker import net.minecraft.init.Blocks import net.minecraft.inventory.InventoryCrafting import net.minecraft.item.ItemStack +import net.minecraft.item.crafting.IRecipe import net.minecraft.nbt.NBTTagCompound import scala.collection.convert.WrapAsScala._ @@ -29,6 +30,7 @@ object ExtendedRecipe { private lazy val navigationUpgrade = api.Items.get("navigationUpgrade") private lazy val linkedCard = api.Items.get("linkedCard") private lazy val floppy = api.Items.get("floppy") + private lazy val lootDisk = api.Items.get("lootDisk") private lazy val robot = api.Items.get("robot") private lazy val tablet = api.Items.get("tablet") private lazy val print = api.Items.get("print") @@ -40,7 +42,7 @@ object ExtendedRecipe { stack } - def addNBTToResult(craftedStack: ItemStack, inventory: InventoryCrafting): ItemStack = { + def addNBTToResult(recipe: IRecipe, craftedStack: ItemStack, inventory: InventoryCrafting): ItemStack = { if (api.Items.get(craftedStack) == navigationUpgrade) { Option(api.Driver.driverFor(craftedStack)).foreach(driver => for (slot <- 0 until inventory.getSizeInventory) { @@ -64,16 +66,22 @@ object ExtendedRecipe { } if (api.Items.get(craftedStack) == floppy) { - if (!craftedStack.hasTagCompound) { - craftedStack.setTagCompound(new NBTTagCompound()) + if (recipe.getRecipeSize == 1) { + // Formatting / loot to normal disk conversion. + craftedStack.setTagCompound(null) } - val nbt = craftedStack.getTagCompound - for (slot <- 0 until inventory.getSizeInventory) { - val stack = inventory.getStackInSlot(slot) - if (stack != null && api.Items.get(stack) == floppy && stack.hasTagCompound) { - val oldData = stack.getTagCompound - for (oldTagName <- oldData.func_150296_c().map(_.asInstanceOf[String])) { - nbt.setTag(oldTagName, oldData.getTag(oldTagName).copy()) + else { + if (!craftedStack.hasTagCompound) { + craftedStack.setTagCompound(new NBTTagCompound()) + } + val nbt = craftedStack.getTagCompound + for (slot <- 0 until inventory.getSizeInventory) { + val stack = inventory.getStackInSlot(slot) + if (stack != null && api.Items.get(stack) == floppy && stack.hasTagCompound) { + val oldData = stack.getTagCompound + for (oldTagName <- oldData.func_150296_c().map(_.asInstanceOf[String])) { + nbt.setTag(oldTagName, oldData.getTag(oldTagName).copy()) + } } } } diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala index 3672d8ed7..552d82a9b 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala @@ -6,5 +6,5 @@ import net.minecraftforge.oredict.ShapedOreRecipe class ExtendedShapedOreRecipe(result: ItemStack, ingredients: AnyRef*) extends ShapedOreRecipe(result, ingredients: _*) { override def getCraftingResult(inventory: InventoryCrafting) = - ExtendedRecipe.addNBTToResult(super.getCraftingResult(inventory), inventory) + ExtendedRecipe.addNBTToResult(this, super.getCraftingResult(inventory), inventory) } diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala index d94e04caa..afd700ff2 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala @@ -6,5 +6,5 @@ import net.minecraftforge.oredict.ShapelessOreRecipe class ExtendedShapelessOreRecipe(result: ItemStack, ingredients: AnyRef*) extends ShapelessOreRecipe(result, ingredients: _*) { override def getCraftingResult(inventory: InventoryCrafting) = - ExtendedRecipe.addNBTToResult(super.getCraftingResult(inventory), inventory) + ExtendedRecipe.addNBTToResult(this, super.getCraftingResult(inventory), inventory) } 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 a5723fb13..99b6bc206 100644 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala @@ -10,6 +10,7 @@ import li.cil.oc._ import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.init.Items import li.cil.oc.common.item.SimpleItem +import li.cil.oc.common.item.data.PrintData import li.cil.oc.integration.Mods import li.cil.oc.integration.util.NEI import li.cil.oc.util.Color @@ -124,6 +125,7 @@ object Recipes { val navigationUpgrade = api.Items.get("navigationUpgrade") val mcu = api.Items.get("microcontroller") val floppy = api.Items.get("floppy") + val lootDisk = api.Items.get("lootDisk") val drone = api.Items.get("drone") val eeprom = api.Items.get("eeprom") val robot = api.Items.get("robot") @@ -188,6 +190,10 @@ object Recipes { } // Print beaconification. + val beaconPrint = print.createItemStack(1) + val printData = new PrintData(beaconPrint) + printData.isBeaconBase = true + printData.save(beaconPrint) for (block <- Array( net.minecraft.init.Blocks.iron_block, net.minecraft.init.Blocks.gold_block, @@ -195,9 +201,13 @@ object Recipes { net.minecraft.init.Blocks.diamond_block )) { GameRegistry.addRecipe(new ExtendedShapelessOreRecipe( - print.createItemStack(1), + beaconPrint, print.createItemStack(1), new ItemStack(block))) } + + // Floppy disk formatting. + GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(floppy.createItemStack(1), floppy.createItemStack(1))) + GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(floppy.createItemStack(1), lootDisk.createItemStack(1))) } catch { case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e) @@ -323,10 +333,10 @@ object Recipes { (inputs, inputCount).zipped.foreach((stacks, count) => stacks.foreach(stack => if (stack != null && count > 0) stack.stackSize = stack.getMaxStackSize min count)) inputs.padTo(2, null) - if (inputs(0) != null) { - for (input1 <- inputs(0)) { - if (inputs(1) != null) { - for (input2 <- inputs(1)) + if (inputs.head != null) { + for (input1 <- inputs.head) { + if (inputs.last != null) { + for (input2 <- inputs.last) gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, input2, output, duration, eu) } else gregtech.api.GregTech_API.sRecipeAdder.addAssemblerRecipe(input1, null, output, duration, eu) diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala index f0d40865c..681b620e8 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala @@ -7,7 +7,6 @@ import appeng.api.config.Settings import appeng.api.config.Upgrades import appeng.api.networking.security.MachineSource import appeng.parts.automation.PartExportBus -import appeng.util.Platform import li.cil.oc.api.driver import li.cil.oc.api.driver.NamedBlock import li.cil.oc.api.driver.EnvironmentAware @@ -26,20 +25,21 @@ import net.minecraft.world.World import net.minecraftforge.common.util.ForgeDirection import scala.collection.convert.WrapAsScala._ -object DriverExportBus extends driver.Block with EnvironmentAware { - type ExportBusTile = appeng.api.parts.IPartHost + +object DriverExportBus extends driver.Block { + type AETileType = appeng.api.parts.IPartHost override def worksWith(world: World, x: Int, y: Int, z: Int) = world.getTileEntity(x, y, z) match { - case container: ExportBusTile => ForgeDirection.VALID_DIRECTIONS.map(container.getPart).exists(_.isInstanceOf[PartExportBus]) + case container: AETileType => ForgeDirection.VALID_DIRECTIONS.map(container.getPart).exists(_.isInstanceOf[PartExportBus]) case _ => false } - override def createEnvironment(world: World, x: Int, y: Int, z: Int) = new Environment(world.getTileEntity(x, y, z).asInstanceOf[ExportBusTile]) + override def createEnvironment(world: World, x: Int, y: Int, z: Int) = new Environment(world.getTileEntity(x, y, z).asInstanceOf[AETileType]) override def providedEnvironment(stack: ItemStack) = if (stack != null && - AEApi.instance != null && + AEApi.instance != null && AEApi.instance.parts() != null && AEApi.instance.parts().partExportBus != null && stack.getItem == AEApi.instance().parts().partExportBus.item() && @@ -47,7 +47,7 @@ object DriverExportBus extends driver.Block with EnvironmentAware { AEApi.instance().parts().partExportBus.stack(1).getItemDamage == stack.getItemDamage) classOf[Environment] else null - class Environment(host: ExportBusTile) extends ManagedTileEntityEnvironment[ExportBusTile](host, "me_exportbus") with NamedBlock { + class Environment(host: AETileType) extends ManagedTileEntityEnvironment[AETileType](host, "me_exportbus") with NamedBlock { override def preferredName = "me_exportbus" override def priority = 2 @@ -128,7 +128,7 @@ object DriverExportBus extends driver.Block with EnvironmentAware { is.stackSize = count if (InventoryUtils.insertIntoInventorySlot(is, inventory, Option(side.getOpposite), targetSlot, count, simulate = true)) { ais.setStackSize(count - is.stackSize) - val eais = Platform.poweredExtraction(export.getProxy.getEnergy, itemStorage, ais, source) + val eais = AEApi.instance.storage.poweredExtraction(export.getProxy.getEnergy, itemStorage, ais, source) if (eais != null) { val eis = eais.getItemStack count -= eis.stackSize @@ -152,4 +152,5 @@ object DriverExportBus extends driver.Block with EnvironmentAware { } } } + } diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala b/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala new file mode 100644 index 000000000..fd2e64f67 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala @@ -0,0 +1,17 @@ +package li.cil.oc.integration.forestry + +import java.util + +import forestry.api.genetics.AlleleManager +import li.cil.oc.api.driver.Converter +import net.minecraft.item.ItemStack + +import scala.collection.convert.WrapAsScala._ + +object ConverterItemStack extends Converter { + override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]): Unit = value match { + case stack: ItemStack if AlleleManager.alleleRegistry.isIndividual(stack) => + output += "individual" -> AlleleManager.alleleRegistry.getIndividual(stack) + case _ => + } +} diff --git a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala b/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala index bc22e9c92..c23dc4e9a 100644 --- a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala +++ b/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala @@ -10,6 +10,7 @@ object ModForestry extends ModProxy { override def initialize() { Driver.add(new ConverterIAlleles) Driver.add(new ConverterIIndividual) + Driver.add(ConverterItemStack) Driver.add(new DriverAnalyzer) Driver.add(new DriverBeeHouse) }