Analyzer can now be used on entities, too, if they implement an appropriate interface (Analyzable, Environment), made that work for drones. Closes #773.

This commit is contained in:
Florian Nücke 2015-01-01 23:27:42 +01:00
parent aed90fc804
commit 44194b6422
4 changed files with 81 additions and 40 deletions

View File

@ -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

View File

@ -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)
}
}

View File

@ -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

View File

@ -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)