From 44194b6422d821e441c6f5320672a9feb832cf58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 1 Jan 2015 23:27:42 +0100 Subject: [PATCH] Analyzer can now be used on entities, too, if they implement an appropriate interface (Analyzable, Environment), made that work for drones. Closes #773. --- .../scala/li/cil/oc/common/entity/Drone.scala | 19 +++- .../li/cil/oc/common/item/Analyzer.scala | 98 ++++++++++++------- .../li/cil/oc/common/item/Delegate.scala | 2 +- .../opencomputers/ModOpenComputers.scala | 2 + 4 files changed, 81 insertions(+), 40 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index dbb372731..345751f05 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -2,6 +2,7 @@ package li.cil.oc.common.entity import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.Localization import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api @@ -38,7 +39,7 @@ import net.minecraftforge.fluids.IFluidTank // internal.Rotatable is also in internal.Drone, but it wasn't since the start // so this is to ensure it is implemented here, in the very unlikely case that // someone decides to ship that specific version of the API. -class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone with internal.Rotatable { +class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone with internal.Rotatable with Analyzable { // Some basic constants. val gravity = 0.05f // low for slow fall (float down) @@ -138,6 +139,22 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern // ----------------------------------------------------------------------- // + override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { + machine.lastError match { + case value if value != null => + player.addChatMessage(Localization.Analyzer.LastError(value)) + case _ => + } + player.addChatMessage(Localization.Analyzer.Components(machine.componentCount, maxComponents)) + val list = machine.users + if (list.size > 0) { + player.addChatMessage(Localization.Analyzer.Users(list)) + } + Array(machine.node) + } + + // ----------------------------------------------------------------------- // + override def cpuArchitecture = info.components.map(stack => (stack, Driver.driverFor(stack, getClass))).collectFirst { case (stack, driver: Processor) if driver.slot(stack) == Slot.CPU => driver.architecture(stack) }.orNull diff --git a/src/main/scala/li/cil/oc/common/item/Analyzer.scala b/src/main/scala/li/cil/oc/common/item/Analyzer.scala index 325071f07..d860edeec 100644 --- a/src/main/scala/li/cil/oc/common/item/Analyzer.scala +++ b/src/main/scala/li/cil/oc/common/item/Analyzer.scala @@ -1,6 +1,8 @@ package li.cil.oc.common.item +import cpw.mods.fml.common.eventhandler.SubscribeEvent import li.cil.oc.Localization +import li.cil.oc.api import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.server.PacketSender @@ -10,52 +12,72 @@ import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayerMP import net.minecraft.item.ItemStack import net.minecraftforge.common.util.ForgeDirection +import net.minecraftforge.event.entity.player.EntityInteractEvent -class Analyzer(val parent: Delegator) extends Delegate { - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { - val world = position.world.get - player match { - case realPlayer: EntityPlayerMP => - world.getTileEntity(position) match { - case analyzable: Analyzable => - if (!world.isRemote) { - analyzeNodes(analyzable.onAnalyze(realPlayer, side, hitX, hitY, hitZ), realPlayer) - } - true - case host: SidedEnvironment => - if (!world.isRemote) { - analyzeNodes(Array(host.sidedNode(ForgeDirection.getOrientation(side))), realPlayer) - } - true - case host: Environment => - if (!world.isRemote) { - analyzeNodes(Array(host.node), realPlayer) - } - true - case _ => super.onItemUse(stack, realPlayer, position, side, hitX, hitY, hitZ) - } - case _ => false +object Analyzer { + private lazy val analyzer = api.Items.get("analyzer") + + @SubscribeEvent + def onInteract(e: EntityInteractEvent): Unit = { + val player = e.entityPlayer + val held = player.getHeldItem + if (api.Items.get(held) == analyzer) { + if (analyze(e.target, player, 0, 0, 0, 0)) + e.setCanceled(true) } } - private def analyzeNodes(nodes: Array[Node], player: EntityPlayerMP) = if (nodes != null) for (node <- nodes if node != null) { - node match { - case connector: Connector => - if (connector.localBufferSize > 0) { - player.addChatMessage(Localization.Analyzer.StoredEnergy(f"${connector.localBuffer}%.2f/${connector.localBufferSize}%.2f")) + def analyze(thing: AnyRef, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + val world = player.worldObj + thing match { + case analyzable: Analyzable => + if (!world.isRemote) { + analyzeNodes(analyzable.onAnalyze(player, side, hitX, hitY, hitZ), player) } - player.addChatMessage(Localization.Analyzer.TotalEnergy(f"${connector.globalBuffer}%.2f/${connector.globalBufferSize}%.2f")) + true + case host: SidedEnvironment => + if (!world.isRemote) { + analyzeNodes(Array(host.sidedNode(ForgeDirection.getOrientation(side))), player) + } + true + case host: Environment => + if (!world.isRemote) { + analyzeNodes(Array(host.node), player) + } + true case _ => + false } - node match { - case component: Component => - player.addChatMessage(Localization.Analyzer.ComponentName(component.name)) + } + + private def analyzeNodes(nodes: Array[Node], player: EntityPlayer) = if (nodes != null) for (node <- nodes if node != null) { + player match { + case playerMP: EntityPlayerMP => + node match { + case connector: Connector => + if (connector.localBufferSize > 0) { + playerMP.addChatMessage(Localization.Analyzer.StoredEnergy(f"${connector.localBuffer}%.2f/${connector.localBufferSize}%.2f")) + } + playerMP.addChatMessage(Localization.Analyzer.TotalEnergy(f"${connector.globalBuffer}%.2f/${connector.globalBufferSize}%.2f")) + case _ => + } + node match { + case component: Component => + playerMP.addChatMessage(Localization.Analyzer.ComponentName(component.name)) + case _ => + } + val address = node.address() + if (address != null && !address.isEmpty) { + playerMP.addChatMessage(Localization.Analyzer.Address(address)) + PacketSender.sendAnalyze(address, playerMP) + } case _ => } - val address = node.address() - if (address != null && !address.isEmpty) { - player.addChatMessage(Localization.Analyzer.Address(address)) - PacketSender.sendAnalyze(address, player) - } + } +} + +class Analyzer(val parent: Delegator) extends Delegate { + override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float) = { + Analyzer.analyze(position.world.get.getTileEntity(position), player, side, hitX, hitY, hitZ) } } 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 eea4e184c..50158123b 100644 --- a/src/main/scala/li/cil/oc/common/item/Delegate.scala +++ b/src/main/scala/li/cil/oc/common/item/Delegate.scala @@ -22,7 +22,7 @@ trait Delegate { type Icon = net.minecraft.util.IIcon type IconRegister = net.minecraft.client.renderer.texture.IIconRegister - val parent: Delegator + def parent: Delegator def unlocalizedName = getClass.getSimpleName diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index ab11eb5b6..06f1138fc 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -12,6 +12,7 @@ import li.cil.oc.common.SaveHandler import li.cil.oc.common.asm.SimpleComponentTickHandler import li.cil.oc.common.entity.Drone import li.cil.oc.common.event._ +import li.cil.oc.common.item.Analyzer import li.cil.oc.common.item.Tablet import li.cil.oc.common.recipe.Recipes import li.cil.oc.common.template._ @@ -47,6 +48,7 @@ object ModOpenComputers extends ModProxy { FMLCommonHandler.instance.bus.register(SimpleComponentTickHandler.Instance) FMLCommonHandler.instance.bus.register(Tablet) + MinecraftForge.EVENT_BUS.register(Analyzer) MinecraftForge.EVENT_BUS.register(AngelUpgradeHandler) MinecraftForge.EVENT_BUS.register(ChunkloaderUpgradeHandler) MinecraftForge.EVENT_BUS.register(EventHandler)