chargers now indicate whether they're on or off by showing a different texture; ability to toggle the way chargers interpret signals using wrenches (inverse: on when no signal, off when max signal); checking if player holds a wrench when activating screens and computer cases; using BuildCraft API entry to check for availability instead of BuildCraft|Energy, to allow working with BC compatible systems even if BC is not available

This commit is contained in:
Florian Nücke 2013-12-16 17:39:09 +01:00
parent 5a617f5ab6
commit 8c14b0f637
10 changed files with 111 additions and 13 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 761 B

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

View File

@ -0,0 +1,32 @@
package buildcraft.api.tools;
import net.minecraft.entity.player.EntityPlayer;
/***
* Implement this interface on subclasses of Item to have that item work as a wrench for buildcraft
*/
public interface IToolWrench {
/***
* Called to ensure that the wrench can be used. To get the ItemStack that is used, check player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates for the block being wrenched
*
* @return true if wrenching is allowed, false if not
*/
public boolean canWrench(EntityPlayer player, int x, int y, int z);
/***
* Callback after the wrench has been used. This can be used to decrease durability or for other purposes. To get the ItemStack that was used, check
* player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates of the block being wrenched
*/
public void wrenchUsed(EntityPlayer player, int x, int y, int z);
}

View File

@ -64,7 +64,9 @@ class PacketHandler extends CommonPacketHandler {
def onChargerState(p: PacketParser) =
p.readTileEntity[Charger]() match {
case Some(t) => t.chargeSpeed = p.readDouble()
case Some(t) =>
t.chargeSpeed = p.readDouble()
t.world.markBlockForRenderUpdate(t.x, t.y, t.z)
case _ => // Invalid packet.
}

View File

@ -3,6 +3,7 @@ package li.cil.oc.common.block
import java.util
import li.cil.oc.common.{GuiType, tileentity}
import li.cil.oc.util.Tooltip
import li.cil.oc.util.mods.BuildCraft
import li.cil.oc.{OpenComputers, Settings}
import net.minecraft.client.renderer.texture.IconRegister
import net.minecraft.entity.player.EntityPlayer
@ -72,7 +73,7 @@ abstract class Case(val parent: SimpleDelegator) extends RedstoneAware with Simp
override def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) = {
if (!player.isSneaking) {
if (!player.isSneaking && !BuildCraft.holdsApplicableWrench(player, x, y, z)) {
if (!world.isRemote) {
player.openGui(OpenComputers, GuiType.Case.id, world, x, y, z)
}

View File

@ -1,9 +1,12 @@
package li.cil.oc.common.block
import cpw.mods.fml.relauncher.{Side, SideOnly}
import java.util
import li.cil.oc.Settings
import li.cil.oc.common.tileentity
import li.cil.oc.server.PacketSender
import li.cil.oc.util.Tooltip
import li.cil.oc.util.mods.BuildCraft
import net.minecraft.client.renderer.texture.IconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
@ -15,6 +18,7 @@ class Charger(val parent: SimpleDelegator) extends RedstoneAware with SimpleDele
val unlocalizedName = "Charger"
private val icons = Array.fill[Icon](6)(null)
private val iconsCharging = Array.fill[Icon](6)(null)
override def tooltipLines(stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
tooltip.addAll(Tooltip.get(unlocalizedName))
@ -22,6 +26,13 @@ class Charger(val parent: SimpleDelegator) extends RedstoneAware with SimpleDele
override def icon(side: ForgeDirection) = Some(icons(side.ordinal()))
@SideOnly(Side.CLIENT)
override def icon(world: IBlockAccess, x: Int, y: Int, z: Int, worldSide: ForgeDirection, localSide: ForgeDirection) =
world.getBlockTileEntity(x, y, z) match {
case charger: tileentity.Charger if charger.chargeSpeed > 0 => Some(iconsCharging(localSide.ordinal()))
case _ => Some(icons(localSide.ordinal()))
}
override def registerIcons(iconRegister: IconRegister) = {
icons(ForgeDirection.DOWN.ordinal) = iconRegister.registerIcon(Settings.resourceDomain + ":generic_top")
icons(ForgeDirection.UP.ordinal) = icons(ForgeDirection.DOWN.ordinal)
@ -30,12 +41,33 @@ class Charger(val parent: SimpleDelegator) extends RedstoneAware with SimpleDele
icons(ForgeDirection.SOUTH.ordinal) = icons(ForgeDirection.NORTH.ordinal)
icons(ForgeDirection.WEST.ordinal) = icons(ForgeDirection.NORTH.ordinal)
icons(ForgeDirection.EAST.ordinal) = icons(ForgeDirection.NORTH.ordinal)
iconsCharging(ForgeDirection.DOWN.ordinal) = icons(ForgeDirection.DOWN.ordinal)
iconsCharging(ForgeDirection.UP.ordinal) = icons(ForgeDirection.UP.ordinal)
iconsCharging(ForgeDirection.NORTH.ordinal) = iconRegister.registerIcon(Settings.resourceDomain + ":charger_on")
iconsCharging(ForgeDirection.SOUTH.ordinal) = iconsCharging(ForgeDirection.NORTH.ordinal)
iconsCharging(ForgeDirection.WEST.ordinal) = iconsCharging(ForgeDirection.NORTH.ordinal)
iconsCharging(ForgeDirection.EAST.ordinal) = iconsCharging(ForgeDirection.NORTH.ordinal)
}
override def createTileEntity(world: World) = Some(new tileentity.Charger())
override def canConnectToRedstone(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true
override def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) =
world.getBlockTileEntity(x, y, z) match {
case charger: tileentity.Charger if BuildCraft.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)
}
true
case _ => super.rightClick(world, x, y, z, player, side, hitX, hitY, hitZ)
}
override def neighborBlockChanged(world: World, x: Int, y: Int, z: Int, blockId: Int) {
world.getBlockTileEntity(x, y, z) match {
case charger: tileentity.Charger => charger.onNeighborChanged()

View File

@ -15,6 +15,7 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
import net.minecraftforge.common.ForgeDirection
import scala.Array
import li.cil.oc.util.mods.BuildCraft
abstract class Screen(val parent: SimpleDelegator) extends SimpleDelegate {
val unlocalizedName = "Screen" + tier
@ -284,7 +285,7 @@ abstract class Screen(val parent: SimpleDelegator) extends SimpleDelegate {
override def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,
side: ForgeDirection, hitX: Float, hitY: Float, hitZ: Float) =
if (!player.isSneaking) {
if (!player.isSneaking && !BuildCraft.holdsApplicableWrench(player, x, y, z)) {
world.getBlockTileEntity(x, y, z) match {
case screen: tileentity.Screen if screen.hasKeyboard =>
// Yep, this GUI is actually purely client side. We could skip this

View File

@ -17,6 +17,8 @@ class Charger extends Environment with RedstoneAware with Analyzable {
var chargeSpeed = 0.0
var invertSignal = false
def onAnalyze(stats: NBTTagCompound, player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = null
override def updateEntity() {
@ -76,7 +78,10 @@ class Charger extends Environment with RedstoneAware with Analyzable {
override protected def onRedstoneInputChanged(side: ForgeDirection) {
super.onRedstoneInputChanged(side)
chargeSpeed = math.max(0, math.min(ForgeDirection.VALID_DIRECTIONS.map(input).max, 15) / 15.0)
val signal = math.max(0, math.min(15, ForgeDirection.VALID_DIRECTIONS.map(input).max))
if (invertSignal) chargeSpeed = (15 - signal) / 15.0
else chargeSpeed = signal / 15.0
if (isServer) {
ServerPacketSender.sendChargerState(this)
}

View File

@ -2,7 +2,7 @@ package li.cil.oc.common.tileentity
import buildcraft.api.power.{PowerHandler, IPowerReceptor}
import cofh.api.energy.IEnergyHandler
import cpw.mods.fml.common.{Loader, Optional}
import cpw.mods.fml.common.{ModAPIManager, Loader, Optional}
import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent}
import ic2.api.energy.tile.IEnergySink
import li.cil.oc.api.network._
@ -16,7 +16,7 @@ import universalelectricity.core.electricity.ElectricityPack
@Optional.InterfaceList(Array(
new Optional.Interface(iface = "ic2.api.energy.tile.IEnergySink", modid = "IC2"),
new Optional.Interface(iface = "buildcraft.api.power.IPowerReceptor", modid = "BuildCraft|Energy"),
new Optional.Interface(iface = "buildcraft.api.power.IPowerReceptor", modid = "BuildCraftAPI|power"),
new Optional.Interface(iface = "cofh.api.energy.IEnergyHandler", modid = "ThermalExpansion")
))
class PowerConverter extends Environment with Analyzable with IEnergySink with IPowerReceptor with IElectrical with IEnergyHandler {
@ -26,7 +26,7 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
private lazy val isIndustrialCraftAvailable = Loader.isModLoaded("IC2")
private lazy val isBuildCraftAvailable = Loader.isModLoaded("BuildCraft|Energy")
private lazy val isBuildCraftAvailable = ModAPIManager.INSTANCE.hasAPI("BuildCraftAPI|power")
private def demand = if (Settings.get.ignorePower) 0.0 else node.globalBufferSize - node.globalBuffer
@ -66,14 +66,14 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
if (Loader.isModLoaded("BuildCraft|Energy")) {
if (ModAPIManager.INSTANCE.hasAPI("BuildCraftAPI|power")) {
getPowerProvider.readFromNBT(nbt.getCompoundTag(Settings.namespace + "bc"))
}
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
if (Loader.isModLoaded("BuildCraft|Energy")) {
if (ModAPIManager.INSTANCE.hasAPI("BuildCraftAPI|power")) {
nbt.setNewCompoundTag(Settings.namespace + "bc", getPowerProvider.writeToNBT)
}
}
@ -133,7 +133,7 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
private var powerHandler: Option[AnyRef] = None
@Optional.Method(modid = "BuildCraft|Energy")
@Optional.Method(modid = "BuildCraftAPI|power")
def getPowerProvider = {
if (node != null && powerHandler.isEmpty) {
val handler = new PowerHandler(this, PowerHandler.Type.MACHINE)
@ -147,16 +147,16 @@ class PowerConverter extends Environment with Analyzable with IEnergySink with I
else null
}
@Optional.Method(modid = "BuildCraft|Energy")
@Optional.Method(modid = "BuildCraftAPI|power")
def getPowerReceiver(side: ForgeDirection) =
if (node != null)
getPowerProvider.getPowerReceiver
else null
@Optional.Method(modid = "BuildCraft|Energy")
@Optional.Method(modid = "BuildCraftAPI|power")
def getWorld = worldObj
@Optional.Method(modid = "BuildCraft|Energy")
@Optional.Method(modid = "BuildCraftAPI|power")
def doWork(workProvider: PowerHandler) {}
// ----------------------------------------------------------------------- //

View File

@ -0,0 +1,25 @@
package li.cil.oc.util.mods
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|core") &&
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|core") &&
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
})
}