Added support for IC2 wrenches and TE hammers as tools for rotating blocks.

Added a new IMC callback for this, registerWrenchTool. Takes a string parameter being the FQN name of a static method with the signature `public static boolean(EntityPlayer player, Int x, Int y, Int z, boolean changeDurability)`. Returns true if item stack held by player is supported.
Split up BC integration into parts for each API package. Just in case someone decides to ship parts of the BC API.
Cleaned up a little.
This commit is contained in:
Florian Nücke 2014-11-27 14:35:56 +01:00
parent 25e340279b
commit 4af6961f7f
26 changed files with 161 additions and 64 deletions

View File

@ -4,7 +4,7 @@ import li.cil.oc.Settings
import li.cil.oc.client.Textures
import li.cil.oc.common.block
import li.cil.oc.common.tileentity.Screen
import li.cil.oc.integration.util.BuildCraft
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.RenderState
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.Tessellator
@ -104,7 +104,7 @@ object ScreenRenderer extends TileEntitySpecialRenderer {
// Show up vector overlay when holding same screen block.
val stack = Minecraft.getMinecraft.thePlayer.getHeldItem
if (stack != null) {
if (BuildCraft.holdsApplicableWrench(Minecraft.getMinecraft.thePlayer, screen.x, screen.y, screen.z) ||
if (Wrench.holdsApplicableWrench(Minecraft.getMinecraft.thePlayer, screen.x, screen.y, screen.z) ||
(stack.getItem match {
case block: block.Item => block.getMetadata(stack.getItemDamage) == screen.getBlockMetadata
case _ => false

View File

@ -120,9 +120,6 @@ object EventHandler {
if (!LuaStateFactory.isAvailable) {
player.addChatMessage(Localization.Chat.WarningLuaFallback)
}
if (Mods.ProjectRedTransmission.isAvailable && !util.ProjectRed.isAPIAvailable) {
player.addChatMessage(Localization.Chat.WarningProjectRed)
}
if (!Settings.get.pureIgnorePower && Settings.get.ignorePower) {
player.addChatMessage(Localization.Chat.WarningPower)
}

View File

@ -8,6 +8,8 @@ import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.template.AssemblerTemplates
import li.cil.oc.integration.util.Wrench
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.Constants.NBT
@ -27,7 +29,7 @@ object IMC {
}
else if (message.key == "registerToolDurabilityProvider" && message.isStringMessage) {
OpenComputers.log.info(s"Registering new tool durability provider '${message.getStringValue}' from mod ${message.getSender}.")
try ToolDurabilityProviders.add(IMC.getStaticMethod(message.getStringValue, classOf[ItemStack])) catch {
try ToolDurabilityProviders.add(getStaticMethod(message.getStringValue, classOf[ItemStack])) catch {
case t: Throwable => OpenComputers.log.warn("Failed registering tool durability provider.", t)
}
}
@ -37,6 +39,12 @@ object IMC {
case t: Throwable => OpenComputers.log.warn("Failed sending config.", t)
}
}
else if (message.key == "registerWrenchTool" && message.isStringMessage) {
OpenComputers.log.info(s"Registering new wrench tool '${message.getStringValue}' from mod ${message.getSender}.")
try Wrench.add(getStaticMethod(message.getStringValue, classOf[EntityPlayer], classOf[Int], classOf[Int], classOf[Int], classOf[Boolean])) catch {
case t: Throwable => OpenComputers.log.warn("Failed registering wrench tool.", t)
}
}
}
}

View File

@ -8,7 +8,7 @@ import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.integration.util.BuildCraft
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.Color
import li.cil.oc.util.Tooltip
import net.minecraft.client.renderer.texture.IIconRegister
@ -78,7 +78,7 @@ class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor {
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
if (!player.isSneaking && !BuildCraft.holdsApplicableWrench(player, x, y, z)) {
if (!player.isSneaking && !Wrench.holdsApplicableWrench(player, x, y, z)) {
if (!world.isRemote) {
player.openGui(OpenComputers, GuiType.Case.id, world, x, y, z)
}

View File

@ -5,7 +5,7 @@ import li.cil.oc.Settings
import li.cil.oc.client.Textures
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.integration.util.BuildCraft
import li.cil.oc.integration.util.Wrench
import li.cil.oc.server.PacketSender
import net.minecraft.block.Block
import net.minecraft.client.renderer.texture.IIconRegister
@ -45,12 +45,12 @@ class Charger extends RedstoneAware with traits.PowerAcceptor {
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) =
world.getTileEntity(x, y, z) match {
case charger: tileentity.Charger =>
if (BuildCraft.holdsApplicableWrench(player, x, y, z)) {
if (Wrench.holdsApplicableWrench(player, x, y, z)) {
if (!world.isRemote) {
charger.invertSignal = !charger.invertSignal
charger.chargeSpeed = 1.0 - charger.chargeSpeed
PacketSender.sendChargerState(charger)
BuildCraft.wrenchUsed(player, x, y, z)
Wrench.wrenchUsed(player, x, y, z)
}
true
}

View File

@ -8,7 +8,7 @@ import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.integration.util.BuildCraft
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.Color
import li.cil.oc.util.PackedColor
import li.cil.oc.util.Tooltip
@ -332,7 +332,7 @@ class Screen(val tier: Int) extends RedstoneAware {
def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) =
if (BuildCraft.holdsApplicableWrench(player, x, y, z)) false
if (Wrench.holdsApplicableWrench(player, x, y, z)) false
else world.getTileEntity(x, y, z) match {
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.invertTouchMode) =>
// Yep, this GUI is actually purely client side. We could skip this

View File

@ -3,7 +3,6 @@ package li.cil.oc.common.tileentity.traits
import cpw.mods.fml.common.Optional
import li.cil.oc.Settings
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.ProjectRed
import li.cil.oc.util.ExtendedNBT._
import mods.immibis.redlogic.api.wiring.IBundledEmitter
import mods.immibis.redlogic.api.wiring.IBundledUpdatable
@ -151,7 +150,7 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledEmitter with IBund
else null
}
else null
val projectRed = if (Mods.ProjectRedTransmission.isAvailable && ProjectRed.isAPIAvailable) {
val projectRed = if (Mods.ProjectRedTransmission.isAvailable) {
Option(ProjectRedAPI.transmissionAPI.getBundledInput(world, x, y, z, side.ordinal)).fold(null: Array[Int])(_.map(_ & 0xFF))
}
else null

View File

@ -22,7 +22,11 @@ object Mods {
val AppliedEnergistics2 = new SimpleMod(IDs.AppliedEnergistics2, version = "@[rv1,)")
val BattleGear2 = new SimpleMod(IDs.BattleGear2)
val BuildCraft = new SimpleMod(IDs.BuildCraft)
val BuildCraftTiles = new SimpleMod(IDs.BuildCraftTiles)
val BuildCraftTools = new SimpleMod(IDs.BuildCraftTools)
val BuildCraftTransport = new SimpleMod(IDs.BuildCraftTransport)
val CoFHEnergy = new SimpleMod(IDs.CoFHEnergy, providesPower = true)
val CoFHItem = new SimpleMod(IDs.CoFHItem)
val CoFHTileEntity = new SimpleMod(IDs.CoFHTileEntity)
val CoFHTransport = new SimpleMod(IDs.CoFHTransport)
val ComputerCraft = new SimpleMod(IDs.ComputerCraft)
@ -74,8 +78,11 @@ object Mods {
def init() {
tryInit(integration.appeng.ModAppEng)
tryInit(integration.buildcraft.ModBuildCraft)
tryInit(integration.buildcraft.tools.ModBuildCraftAPITools)
tryInit(integration.buildcraft.tiles.ModBuildCraftAPITiles)
tryInit(integration.buildcraft.transport.ModBuildCraftAPITransport)
tryInit(integration.cofh.energy.ModCoFHEnergy)
tryInit(integration.cofh.item.ModCoFHItem)
tryInit(integration.cofh.tileentity.ModCoFHTileEntity)
tryInit(integration.cofh.transport.ModCoFHTransport)
tryInit(integration.enderstorage.ModEnderStorage)
@ -123,7 +130,11 @@ object Mods {
final val BattleGear2 = "battlegear2"
final val BuildCraft = "BuildCraft|Core"
final val BuildCraftPower = "BuildCraftAPI|power"
final val BuildCraftTiles = "BuildCraftAPI|tiles"
final val BuildCraftTools = "BuildCraftAPI|tools"
final val BuildCraftTransport = "BuildCraftAPI|transport"
final val CoFHEnergy = "CoFHAPI|energy"
final val CoFHItem = "CoFHAPI|item"
final val CoFHTileEntity = "CoFHAPI|tileentity"
final val CoFHTransport = "CoFHAPI|transport"
final val ComputerCraft = "ComputerCraft"

View File

@ -1,4 +1,4 @@
package li.cil.oc.integration.buildcraft;
package li.cil.oc.integration.buildcraft.tiles;
import buildcraft.api.tiles.IControllable;
import li.cil.oc.api.machine.Arguments;

View File

@ -1,14 +1,13 @@
package li.cil.oc.integration.buildcraft
package li.cil.oc.integration.buildcraft.tiles
import li.cil.oc.api.Driver
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
object ModBuildCraft extends ModProxy {
override def getMod = Mods.BuildCraft
object ModBuildCraftAPITiles extends ModProxy {
override def getMod = Mods.BuildCraftTiles
override def initialize() {
Driver.add(new DriverPipeTile)
Driver.add(new DriverControllable)
}
}
}

View File

@ -0,0 +1,18 @@
package li.cil.oc.integration.buildcraft.tools
import buildcraft.api.tools.IToolWrench
import net.minecraft.entity.player.EntityPlayer
object EventHandlerBuildCraft {
def useWrench(player: EntityPlayer, x: Int, y: Int, z: Int, changeDurability: Boolean): Boolean = {
player.getCurrentEquippedItem.getItem match {
case wrench: IToolWrench =>
if (changeDurability) {
wrench.wrenchUsed(player, x, y, z)
true
}
else wrench.canWrench(player, x, y, z)
case _ => false
}
}
}

View File

@ -0,0 +1,13 @@
package li.cil.oc.integration.buildcraft.tools
import cpw.mods.fml.common.event.FMLInterModComms
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
object ModBuildCraftAPITools extends ModProxy {
override def getMod = Mods.BuildCraftTools
override def initialize(): Unit = {
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.buildcraft.tools.EventHandlerBuildCraft.useWrench")
}
}

View File

@ -1,4 +1,4 @@
package li.cil.oc.integration.buildcraft;
package li.cil.oc.integration.buildcraft.transport;
import buildcraft.api.transport.IPipeTile;
import buildcraft.api.transport.PipeWire;

View File

@ -0,0 +1,13 @@
package li.cil.oc.integration.buildcraft.transport
import li.cil.oc.api.Driver
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
object ModBuildCraftAPITransport extends ModProxy {
override def getMod = Mods.BuildCraftTransport
override def initialize() {
Driver.add(new DriverPipeTile)
}
}

View File

@ -10,7 +10,7 @@ object ModCoFHEnergy extends ModProxy {
override def getMod = Mods.CoFHEnergy
override def initialize() {
FMLInterModComms.sendMessage("OpenComputers", "registerToolDurabilityProvider", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.cofh.energy.EventHandlerRedstoneFlux.getDurability")
MinecraftForge.EVENT_BUS.register(EventHandlerRedstoneFlux)

View File

@ -0,0 +1,18 @@
package li.cil.oc.integration.cofh.item
import cofh.api.item.IToolHammer
import net.minecraft.entity.player.EntityPlayer
object EventHandlerCoFH {
def useWrench(player: EntityPlayer, x: Int, y: Int, z: Int, changeDurability: Boolean): Boolean = {
player.getCurrentEquippedItem.getItem match {
case wrench: IToolHammer =>
if (changeDurability) {
wrench.toolUsed(player.getHeldItem, player, x, y, z)
true
}
else wrench.isUsable(player.getHeldItem, player, x, y, z)
case _ => false
}
}
}

View File

@ -0,0 +1,13 @@
package li.cil.oc.integration.cofh.item
import cpw.mods.fml.common.event.FMLInterModComms
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
object ModCoFHItem extends ModProxy {
override def getMod = Mods.CoFHItem
override def initialize(): Unit = {
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.cofh.item.EventHandlerCoFH.useWrench")
}
}

View File

@ -2,14 +2,15 @@ package li.cil.oc.integration.gregtech
import cpw.mods.fml.common.event.FMLInterModComms
import li.cil.oc.api.Driver
import li.cil.oc.integration.{ModProxy, Mods}
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
import net.minecraftforge.common.MinecraftForge
object ModGregtech extends ModProxy {
override def getMod = Mods.GregTech
override def initialize() {
FMLInterModComms.sendMessage("OpenComputers", "registerToolDurabilityProvider", "li.cil.oc.integration.gregtech.EventHandlerGregTech.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.gregtech.EventHandlerGregTech.getDurability")
MinecraftForge.EVENT_BUS.register(EventHandlerGregTech)

View File

@ -1,8 +1,12 @@
package li.cil.oc.integration.ic2
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import ic2.api.item.{ElectricItem, IElectricItem, ISpecialElectricItem}
import ic2.api.item.ElectricItem
import ic2.api.item.IElectricItem
import ic2.api.item.ISpecialElectricItem
import ic2.core.item.tool.ItemToolWrench
import li.cil.oc.api.event.RobotUsedToolEvent
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
object EventHandlerIndustrialCraft2 {
@ -41,4 +45,16 @@ object EventHandlerIndustrialCraft2 {
case _ => Double.NaN
}
}
def useWrench(player: EntityPlayer, x: Int, y: Int, z: Int, changeDurability: Boolean): Boolean = {
player.getCurrentEquippedItem.getItem match {
case wrench: ItemToolWrench =>
if (changeDurability) {
wrench.damage(player.getHeldItem, 1, player)
true
}
else wrench.canTakeDamage(player.getHeldItem, 1)
case _ => false
}
}
}

View File

@ -2,14 +2,17 @@ package li.cil.oc.integration.ic2
import cpw.mods.fml.common.event.FMLInterModComms
import li.cil.oc.api.Driver
import li.cil.oc.integration.{ModProxy, Mods}
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
import net.minecraftforge.common.MinecraftForge
object ModIndustrialCraft2 extends ModProxy {
override def getMod = Mods.IndustrialCraft2
override def initialize() {
FMLInterModComms.sendMessage("OpenComputers", "registerToolDurabilityProvider", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerWrenchTool", "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.useWrench")
MinecraftForge.EVENT_BUS.register(EventHandlerIndustrialCraft2)

View File

@ -9,7 +9,7 @@ object ModTinkersConstruct extends ModProxy {
override def getMod = Mods.TinkersConstruct
override def initialize() {
FMLInterModComms.sendMessage("OpenComputers", "registerToolDurabilityProvider", "li.cil.oc.integration.tcon.EventHandlerTinkersConstruct.getDurability")
FMLInterModComms.sendMessage(Mods.IDs.OpenComputers, "registerToolDurabilityProvider", "li.cil.oc.integration.tcon.EventHandlerTinkersConstruct.getDurability")
MinecraftForge.EVENT_BUS.register(EventHandlerTinkersConstruct)
}

View File

@ -1,25 +0,0 @@
package li.cil.oc.integration.util
import buildcraft.api.tools.IToolWrench
import cpw.mods.fml.common.ModAPIManager
import net.minecraft.entity.player.EntityPlayer
object BuildCraft {
def holdsApplicableWrench(player: EntityPlayer, x: Int, y: Int, z: Int) =
ModAPIManager.INSTANCE.hasAPI("BuildCraftAPI|tools") &&
player.getCurrentEquippedItem != null &&
(player.getCurrentEquippedItem.getItem match {
case wrench: IToolWrench => wrench.canWrench(player, x, y, z)
case _ => false
})
def wrenchUsed(player: EntityPlayer, x: Int, y: Int, z: Int) =
ModAPIManager.INSTANCE.hasAPI("BuildCraftAPI|tools") &&
player.getCurrentEquippedItem != null &&
(player.getCurrentEquippedItem.getItem match {
case wrench: IToolWrench if wrench.canWrench(player, x, y, z) =>
wrench.wrenchUsed(player, x, y, z)
true
case _ => false
})
}

View File

@ -5,5 +5,5 @@ import li.cil.oc.integration.Mods
object BundledRedstone {
def isAvailable = Mods.RedLogic.isAvailable ||
Mods.MineFactoryReloaded.isAvailable ||
(Mods.ProjectRedTransmission.isAvailable && ProjectRed.isAPIAvailable)
Mods.ProjectRedTransmission.isAvailable
}

View File

@ -1,7 +0,0 @@
package li.cil.oc.integration.util
import mrtjp.projectred.api.ProjectRedAPI
object ProjectRed {
def isAPIAvailable = classOf[ProjectRedAPI].getFields.exists(_.getName == "transmissionAPI")
}

View File

@ -0,0 +1,20 @@
package li.cil.oc.integration.util
import java.lang.reflect.Method
import li.cil.oc.common.IMC
import net.minecraft.entity.player.EntityPlayer
import scala.collection.mutable
object Wrench {
private val wrenches = mutable.LinkedHashSet.empty[Method]
def add(wrench: Method): Unit = wrenches += wrench
def holdsApplicableWrench(player: EntityPlayer, x: Int, y: Int, z: Int): Boolean =
player.getCurrentEquippedItem != null && wrenches.exists(IMC.tryInvokeStatic(_, player, int2Integer(x), int2Integer(y), int2Integer(z), boolean2Boolean(false))(false))
def wrenchUsed(player: EntityPlayer, x: Int, y: Int, z: Int): Unit =
if (player.getCurrentEquippedItem != null) wrenches.foreach(IMC.tryInvokeStaticVoid(_, player, int2Integer(x), int2Integer(y), int2Integer(z), boolean2Boolean(true)))
}

View File

@ -8,6 +8,6 @@ object ModWaila extends ModProxy {
override def getMod = Mods.Waila
override def initialize() {
FMLInterModComms.sendMessage("Waila", "register", "li.cil.oc.integration.waila.BlockDataProvider.init")
FMLInterModComms.sendMessage(Mods.IDs.Waila, "register", "li.cil.oc.integration.waila.BlockDataProvider.init")
}
}