Fixed a couple more compile errors; hackjob of an implementation of new IFluidHandler stuff. Kickd MCMP for now, too much other stuff to fix first.

This commit is contained in:
Florian Nücke 2017-02-25 17:10:27 +01:00
parent 43fe39edd1
commit b48c2098ab
90 changed files with 267 additions and 1893 deletions

View File

@ -3,7 +3,6 @@ package li.cil.oc.api.internal;
import li.cil.oc.api.network.EnvironmentHost;
import li.cil.oc.api.network.Environment;
import net.minecraft.inventory.ISidedInventory;
import net.minecraftforge.fluids.IFluidHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@ -29,7 +28,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
* <p/>
* This interface is <em>not meant to be implemented</em>, just used.
*/
public interface Robot extends Agent, Environment, EnvironmentHost, Tiered, ISidedInventory, IFluidHandler {
public interface Robot extends Agent, Environment, EnvironmentHost, Tiered, ISidedInventory {
/**
* The number of built-in components in this robot.
*/

View File

@ -12,7 +12,7 @@ object CommandHandler {
}
object SetClipboardCommand extends SimpleCommand("oc_setclipboard") {
override def getCommandUsage(source: ICommandSender): String = name + " <value>"
override def getUsage(source: ICommandSender): String = name + " <value>"
override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = {
if (source.getEntityWorld.isRemote && command != null && command.length > 0) {

View File

@ -146,7 +146,7 @@ object PacketHandler extends CommonPacketHandler {
p.readTileEntity[Colored]() match {
case Some(t) =>
t.setColor(p.readInt())
t.world.notifyBlockUpdate(t.position)
t.getWorld.notifyBlockUpdate(t.position)
case _ => // Invalid packet.
}

View File

@ -109,25 +109,6 @@ object EventHandler {
}
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def scheduleIC2Add(tileEntity: power.IndustrialCraft2Experimental) {
if (SideTracker.isServer) pendingServer.synchronized {
pendingServer += (() => if (!tileEntity.addedToIC2PowerGrid && !tileEntity.isInvalid) {
MinecraftForge.EVENT_BUS.post(new ic2.api.energy.event.EnergyTileLoadEvent(tileEntity.asInstanceOf[ic2.api.energy.tile.IEnergySink]))
tileEntity.addedToIC2PowerGrid = true
})
}
}
def scheduleWirelessRedstone(rs: server.component.RedstoneWireless) {
if (SideTracker.isServer) pendingServer.synchronized {
pendingServer += (() => if (rs.node.network != null) {
util.WirelessRedstone.addReceiver(rs)
util.WirelessRedstone.updateOutput(rs)
})
}
}
@SubscribeEvent
def onAttachCapabilities(event: AttachCapabilitiesEvent.TileEntity): Unit = {
event.getTileEntity match {
@ -232,7 +213,7 @@ object EventHandler {
})
// Do update check in local games and for OPs.
val server = FMLCommonHandler.instance.getMinecraftServerInstance
if (!Mods.VersionChecker.isAvailable && (!server.isDedicatedServer || server.getPlayerList.canSendCommands(player.getGameProfile))) {
if (!server.isDedicatedServer || server.getPlayerList.canSendCommands(player.getGameProfile)) {
Future {
UpdateCheck.info onSuccess {
case Some(release) => player.sendMessage(Localization.Chat.InfoNewVersion(release.tag_name))

View File

@ -20,7 +20,7 @@ class Adapter extends SimpleBlock with traits.GUI {
// ----------------------------------------------------------------------- //
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block): Unit =
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit =
world.getTileEntity(pos) match {
case adapter: tileentity.Adapter => adapter.neighborChanged()
case _ => // Ignore.

View File

@ -3,7 +3,6 @@ package li.cil.oc.common.block
import li.cil.oc.Settings
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import net.minecraft.block.state.IBlockState
import net.minecraft.util.EnumFacing
import net.minecraft.util.math.BlockPos
@ -11,8 +10,6 @@ import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI {
ModColoredLights.setLightLevel(this, 0, 3, 5)
override def isOpaqueCube(state: IBlockState): Boolean = false
override def isFullCube(state: IBlockState): Boolean = false

View File

@ -3,15 +3,12 @@ package li.cil.oc.common.block
import java.util.Random
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
class Capacitor extends SimpleBlock {
ModColoredLights.setLightLevel(this, 5, 5, 5)
setTickRandomly(true)
// ----------------------------------------------------------------------- //
@ -35,7 +32,7 @@ class Capacitor extends SimpleBlock {
override def tickRate(world: World) = 1
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block): Unit =
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit =
world.getTileEntity(pos) match {
case capacitor: tileentity.Capacitor => capacitor.recomputeCapacity()
case _ =>

View File

@ -52,11 +52,11 @@ class Charger extends RedstoneAware with traits.PowerAcceptor with traits.StateA
}
else super.localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ)
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block): Unit = {
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = {
world.getTileEntity(pos) match {
case charger: tileentity.Charger => charger.onNeighborChanged()
case _ =>
}
super.neighborChanged(state, world, pos, neighborBlock)
super.neighborChanged(state, world, pos, block, fromPos)
}
}

View File

@ -23,15 +23,6 @@ class DiskDrive extends SimpleBlock with traits.GUI {
// ----------------------------------------------------------------------- //
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: java.util.List[String], advanced: Boolean) {
super.tooltipTail(metadata, stack, player, tooltip, advanced)
if (Mods.ComputerCraft.isAvailable) {
tooltip.addAll(Tooltip.get(getClass.getSimpleName + ".CC"))
}
}
// ----------------------------------------------------------------------- //
override def guiType = GuiType.DiskDrive
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.DiskDrive()

View File

@ -1,13 +1,8 @@
package li.cil.oc.common.block
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import net.minecraft.world.World
class Geolyzer extends SimpleBlock {
ModColoredLights.setLightLevel(this, 3, 1, 1)
// ----------------------------------------------------------------------- //
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Geolyzer()
}

View File

@ -2,9 +2,7 @@ package li.cil.oc.common.block
import java.util
import li.cil.oc.Settings
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import li.cil.oc.util.Rarity
import li.cil.oc.util.Tooltip
import net.minecraft.block.state.IBlockState
@ -19,10 +17,6 @@ import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
class Hologram(val tier: Int) extends SimpleBlock {
if (Settings.get.hologramLight) {
ModColoredLights.setLightLevel(this, 15, 15, 15)
}
val bounds = new AxisAlignedBB(0, 0, 0, 1, 0.5f, 1)
// ----------------------------------------------------------------------- //

View File

@ -92,7 +92,7 @@ class Keyboard extends SimpleBlock(Material.ROCK) {
})
}
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block): Unit =
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit =
world.getTileEntity(pos) match {
case keyboard: tileentity.Keyboard =>
if (!canPlaceBlockOnSide(world, pos, keyboard.facing)) {

View File

@ -35,7 +35,7 @@ class NetSplitter extends RedstoneAware {
// ----------------------------------------------------------------------- //
// NOTE: must not be final for immibis microblocks to work.
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
if (Wrench.holdsApplicableWrench(player, pos)) {
val sideToToggle = if (player.isSneaking) side.getOpposite else side
world.getTileEntity(pos) match {
@ -48,6 +48,6 @@ class NetSplitter extends RedstoneAware {
case _ => false
}
}
else super.onBlockActivated(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ)
else super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ)
}
}

View File

@ -24,19 +24,10 @@ class PowerConverter extends SimpleBlock with traits.PowerAcceptor {
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
super.tooltipTail(metadata, stack, player, tooltip, advanced)
if (Mods.Factorization.isAvailable) {
addRatio(tooltip, "Factorization", Settings.get.ratioFactorization)
}
if (Mods.IndustrialCraft2.isAvailable || Mods.IndustrialCraft2Classic.isAvailable) {
addRatio(tooltip, "IndustrialCraft2", Settings.get.ratioIndustrialCraft2)
}
if (Mods.Mekanism.isAvailable) {
addRatio(tooltip, "Mekanism", Settings.get.ratioMekanism)
}
if (Mods.CoFHEnergy.isAvailable) {
addRatio(tooltip, "ThermalExpansion", Settings.get.ratioRedstoneFlux)
}
// TODO more generic way of integration modules of power providing mods to provide tooltip lines
// if (Mods.Factorization.isAvailable) {
// addRatio(tooltip, "Factorization", Settings.get.ratioFactorization)
// }
}
private def addExtension(x: Double) =

View File

@ -1,14 +1,9 @@
package li.cil.oc.common.block
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import net.minecraft.world.World
class PowerDistributor extends SimpleBlock {
ModColoredLights.setLightLevel(this, 5, 5, 3)
// ----------------------------------------------------------------------- //
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.PowerDistributor()
}

View File

@ -90,8 +90,6 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
case _ => super.getLightOpacity(state, world, pos)
}
override def isVisuallyOpaque = false
override def isFullCube(state: IBlockState): Boolean = false
override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true
@ -159,10 +157,10 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
// ----------------------------------------------------------------------- //
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
world.getTileEntity(pos) match {
case print: tileentity.Print => print.activate()
case _ => super.onBlockActivated(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ)
case _ => super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ)
}
}
@ -171,7 +169,7 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
tileEntity.data.load(stack)
tileEntity.updateBounds()
tileEntity.updateRedstone()
tileEntity.world.checkLight(tileEntity.getPos)
tileEntity.getWorld.checkLight(tileEntity.getPos)
}
override protected def doCustomDrops(tileEntity: tileentity.Print, player: EntityPlayer, willHarvest: Boolean): Unit = {

View File

@ -12,15 +12,10 @@ import net.minecraft.world.World
class Redstone extends RedstoneAware {
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
super.tooltipTail(metadata, stack, player, tooltip, advanced)
if (Mods.ProjectRedTransmission.isAvailable) {
tooltip.addAll(Tooltip.get("RedstoneCard.ProjectRed"))
}
if (Mods.RedLogic.isAvailable) {
tooltip.addAll(Tooltip.get("RedstoneCard.RedLogic"))
}
if (Mods.MineFactoryReloaded.isAvailable) {
tooltip.addAll(Tooltip.get("RedstoneCard.RedNet"))
}
// todo more generic way for redstone mods to provide lines
// if (Mods.ProjectRedTransmission.isAvailable) {
// tooltip.addAll(Tooltip.get("RedstoneCard.ProjectRed"))
// }
}
// ----------------------------------------------------------------------- //

View File

@ -1,22 +1,14 @@
package li.cil.oc.common.block
import li.cil.oc.common.tileentity
import li.cil.oc.integration.Mods
import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState
import net.minecraft.util.EnumFacing
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
import net.minecraftforge.fml.common.Optional
/* TODO MFR
import powercrystals.minefactoryreloaded.api.rednet.IRedNetNetworkContainer
import powercrystals.minefactoryreloaded.api.rednet.IRedNetOmniNode
import powercrystals.minefactoryreloaded.api.rednet.connectivity.RedNetConnectionType
*/
@Optional.Interface(iface = "powercrystals.minefactoryreloaded.api.rednet.IRedNetOmniNode", modid = Mods.IDs.MineFactoryReloaded)
abstract class RedstoneAware extends SimpleBlock /* with IRedNetOmniNode TODO MFR */ {
abstract class RedstoneAware extends SimpleBlock {
override def canProvidePower(state: IBlockState): Boolean = true
override def canConnectRedstone(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean =
@ -36,54 +28,10 @@ abstract class RedstoneAware extends SimpleBlock /* with IRedNetOmniNode TODO MF
// ----------------------------------------------------------------------- //
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block): Unit = {
/* TODO MFR
if (Mods.MineFactoryReloaded.isAvailable) {
val position = BlockPosition(x, y, z)
world.getTileEntity(position) match {
case t: tileentity.traits.BundledRedstoneAware => for (side <- EnumFacing.values) {
world.getBlock(position.offset(side)) match {
case block: IRedNetNetworkContainer =>
case _ => for (color <- 0 until 16) {
t.rednetInput(side, color, 0)
}
}
}
case _ =>
}
}
*/
override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = {
world.getTileEntity(pos) match {
case redstone: tileentity.traits.RedstoneAware => redstone.checkRedstoneInputChanged()
case _ => // Ignore.
}
}
// ----------------------------------------------------------------------- //
/* TODO MFR
override def getConnectionType(world: World, x: Int, y: Int, z: Int, side: EnumFacing) = RedNetConnectionType.CableAll
override def getOutputValue(world: World, x: Int, y: Int, z: Int, side: EnumFacing, color: Int) =
world.getTileEntity(x, y, z) match {
case t: tileentity.traits.BundledRedstoneAware => t.bundledOutput(side, color)
case _ => 0
}
override def getOutputValues(world: World, x: Int, y: Int, z: Int, side: EnumFacing) =
world.getTileEntity(x, y, z) match {
case t: tileentity.traits.BundledRedstoneAware => t.bundledOutput(side)
case _ => Array.fill(16)(0)
}
override def onInputChanged(world: World, x: Int, y: Int, z: Int, side: EnumFacing, inputValue: Int) {}
override def onInputsChanged(world: World, x: Int, y: Int, z: Int, side: EnumFacing, inputValues: Array[Int]) =
world.getTileEntity(x, y, z) match {
case t: tileentity.traits.BundledRedstoneAware => for (color <- 0 until 16) {
t.rednetInput(side, color, inputValues(color))
}
case _ =>
}
*/
}

View File

@ -24,15 +24,12 @@ import li.cil.oc.common.GuiType
import li.cil.oc.common.block.property.PropertyRotatable
import li.cil.oc.common.block.property.PropertyTile
import li.cil.oc.common.tileentity
import li.cil.oc.integration.coloredlights.ModColoredLights
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.PackedColor
import li.cil.oc.util.Rarity
import li.cil.oc.util.Tooltip
class Screen(val tier: Int) extends RedstoneAware {
ModColoredLights.setLightLevel(this, 5, 5, 5)
override def createBlockState() = new ExtendedBlockState(this, Array(PropertyRotatable.Pitch, PropertyRotatable.Yaw), Array(PropertyTile.Tile))
override def getMetaFromState(state: IBlockState): Int = (state.getValue(PropertyRotatable.Pitch).ordinal() << 2) | state.getValue(PropertyRotatable.Yaw).getHorizontalIndex

View File

@ -154,8 +154,8 @@ abstract class SimpleBlock(material: Material = Material.IRON) extends BlockCont
// ----------------------------------------------------------------------- //
// NOTE: must not be final for immibis microblocks to work.
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean =
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, facing: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
val heldItem = player.getHeldItem(hand)
world.getTileEntity(pos) match {
case colored: Colored if Color.isDye(heldItem) =>
colored.setColor(Color.rgbValues(Color.dyeColor(heldItem)))
@ -164,8 +164,9 @@ abstract class SimpleBlock(material: Material = Material.IRON) extends BlockCont
heldItem.splitStack(1)
}
true
case _ => localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ)
case _ => localOnBlockActivated(world, pos, player, hand, heldItem, facing, hitX, hitY, hitZ)
}
}
def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = false
}

View File

@ -13,9 +13,9 @@ import scala.collection.mutable
abstract class SimpleCommand(val name: String) extends CommandBase {
protected var aliases = mutable.ListBuffer.empty[String]
override def getCommandName = name
override def getName = name
override def getCommandAliases: util.List[String] = aliases
override def getAliases: util.List[String] = aliases
override def checkPermission(server: MinecraftServer, sender: ICommandSender): Boolean = super.checkPermission(server, sender)|| (FMLCommonHandler.instance().getMinecraftServerInstance != null && FMLCommonHandler.instance().getMinecraftServerInstance.isSinglePlayer)

View File

@ -31,12 +31,12 @@ abstract class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int)
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack)
override def onTake(player: EntityPlayer, stack: ItemStack) {
super.onTake(player, stack)
override def onTake(player: EntityPlayer, stack: ItemStack) = {
for (slot <- container.inventorySlots) slot match {
case dynamic: ComponentSlot => dynamic.clearIfInvalid(player)
case _ =>
}
super.onTake(player, stack)
}
override def putStack(stack: ItemStack): Unit = {

View File

@ -64,7 +64,7 @@ object Drone {
// 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 with Analyzable with Context {
class Drone(world: World) extends Entity(world) with MachineHost with internal.Drone with internal.Rotatable with Analyzable with Context {
// Some basic constants.
val gravity = 0.05f
// low for slow fall (float down)

View File

@ -47,6 +47,8 @@ object BlockChangeHandler {
}
}
override def spawnParticle(id: Int, ignoreRange: Boolean, p_190570_3_ : Boolean, x: Double, y: Double, z: Double, xSpeed: Double, ySpeed: Double, zSpeed: Double, parameters: Int*): Unit = {}
override def playRecord(soundIn: SoundEvent, pos: BlockPos): Unit = {}
override def playEvent(player: EntityPlayer, `type`: Int, blockPosIn: BlockPos, data: Int): Unit = {}

View File

@ -332,7 +332,6 @@ object Items extends ItemAPI {
initUpgrades()
initStorage()
initSpecial()
initIntegration()
// Register aliases.
for ((k, v) <- aliases) {
@ -539,15 +538,6 @@ object Items extends ItemAPI {
registerItem(new item.Present(misc), Constants.ItemName.Present)
}
// Items used for integration with other mods.
private def initIntegration(): Unit = {
val integration = newItem(new item.Delegator(), "integration")
// Only register recipes if the related mods are present.
Recipes.addSubItem(new item.AbstractBusCard(integration), Constants.ItemName.AbstractBusCard, Mods.StargateTech2.isAvailable, "oc:abstractBusCard")
Recipes.addSubItem(new item.WorldSensorCard(integration), Constants.ItemName.WorldSensorCard, Mods.Galacticraft.isAvailable, "oc:worldSensorCard")
}
private def newItem[T <: Item](item: T, name: String): T = {
item.setUnlocalizedName("oc." + name)
GameRegistry.register(item, new ResourceLocation(Settings.resourceDomain, name))

View File

@ -1,7 +0,0 @@
package li.cil.oc.common.item
import li.cil.oc.integration.Mods
class AbstractBusCard(val parent: Delegator) extends traits.Delegate with traits.ItemTier {
showInItemList = Mods.StargateTech2.isAvailable
}

View File

@ -3,8 +3,6 @@ package li.cil.oc.common.item
import java.util
import li.cil.oc.common.Tier
import li.cil.oc.integration.Mods
import li.cil.oc.util.Tooltip
import net.minecraft.item.ItemStack
class RedstoneCard(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier {
@ -18,21 +16,10 @@ class RedstoneCard(val parent: Delegator, val tier: Int) extends traits.Delegate
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) {
super.tooltipExtended(stack, tooltip)
if (tier == Tier.Two) {
if (Mods.ProjectRedTransmission.isAvailable) {
tooltip.addAll(Tooltip.get(super.unlocalizedName + ".ProjectRed"))
}
if (Mods.RedLogic.isAvailable) {
tooltip.addAll(Tooltip.get(super.unlocalizedName + ".RedLogic"))
}
if (Mods.MineFactoryReloaded.isAvailable) {
tooltip.addAll(Tooltip.get(super.unlocalizedName + ".RedNet"))
}
if (Mods.WirelessRedstoneCBE.isAvailable) {
tooltip.addAll(Tooltip.get(super.unlocalizedName + ".WirelessCBE"))
}
if (Mods.WirelessRedstoneSVE.isAvailable) {
tooltip.addAll(Tooltip.get(super.unlocalizedName + ".WirelessSV"))
}
// TODO Generic system for redstone integration modules to register in a list of tooltip lines.
// if (Mods.MOD_NAME.isAvailable) {
// tooltip.addAll(Tooltip.get(super.unlocalizedName + ".MOD_NAME"))
// }
}
}
}

View File

@ -1,7 +0,0 @@
package li.cil.oc.common.item
import li.cil.oc.integration.Mods
class WorldSensorCard(val parent: Delegator) extends traits.Delegate with traits.ItemTier {
showInItemList = Mods.Galacticraft.isAvailable
}

View File

@ -1,12 +1,7 @@
package li.cil.oc.common.item
import li.cil.oc.api
import li.cil.oc.common.asm.Injectable
import li.cil.oc.integration.Mods
import net.minecraft.block.Block
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.item.EntityMinecart
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.init.Blocks
import net.minecraft.item.ItemStack
@ -17,18 +12,6 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockAccess
import net.minecraft.world.World
@Injectable.InterfaceList(Array(
new Injectable.Interface(value = "appeng.api.implementations.items.IAEWrench", modid = Mods.IDs.AppliedEnergistics2),
new Injectable.Interface(value = "buildcraft.api.tools.IToolWrench", modid = Mods.IDs.BuildCraftTools),
new Injectable.Interface(value = "com.bluepowermod.api.misc.IScrewdriver", modid = Mods.IDs.BluePower),
new Injectable.Interface(value = "cofh.api.item.IToolHammer", modid = Mods.IDs.CoFHItem),
new Injectable.Interface(value = "crazypants.enderio.api.tool.ITool", modid = Mods.IDs.EnderIO),
new Injectable.Interface(value = "mekanism.api.IMekWrench", modid = Mods.IDs.Mekanism),
new Injectable.Interface(value = "powercrystals.minefactoryreloaded.api.IMFRHammer", modid = Mods.IDs.MineFactoryReloaded),
new Injectable.Interface(value = "mrtjp.projectred.api.IScrewdriver", modid = Mods.IDs.ProjectRedCore),
new Injectable.Interface(value = "mods.railcraft.api.core.items.IToolCrowbar", modid = Mods.IDs.Railcraft),
new Injectable.Interface(value = "ic2.api.item.IBoxable", modid = Mods.IDs.IndustrialCraft2)
))
class Wrench extends traits.SimpleItem with api.internal.Wrench {
setHarvestLevel("wrench", 1)
setMaxStackSize(1)
@ -51,80 +34,4 @@ class Wrench extends traits.SimpleItem with api.internal.Wrench {
if (!simulate) player.swingArm(EnumHand.MAIN_HAND)
true
}
// Applied Energistics 2
def canWrench(stack: ItemStack, player: EntityPlayer, pos: BlockPos): Boolean = true
// BluePower
def damage(stack: ItemStack, damage: Int, player: EntityPlayer, simulated: Boolean): Boolean = damage == 0
// BuildCraft
def canWrench(player: EntityPlayer, pos: BlockPos): Boolean = true
def wrenchUsed(player: EntityPlayer, pos: BlockPos): Unit = player.swingArm(EnumHand.MAIN_HAND)
def canWrench(player: EntityPlayer, entity: Entity): Boolean = true
def wrenchUsed(player: EntityPlayer, entity: Entity): Unit = player.swingArm(EnumHand.MAIN_HAND)
// CoFH
def isUsable(stack: ItemStack, player: EntityLivingBase, pos: BlockPos): Boolean = true
def isUsable(stack: ItemStack, player: EntityLivingBase, entity: Entity): Boolean = true
def toolUsed(stack: ItemStack, player: EntityLivingBase, pos: BlockPos): Unit = player.swingArm(EnumHand.MAIN_HAND)
def toolUsed(stack: ItemStack, player: EntityLivingBase, entity: Entity): Unit = player.swingArm(EnumHand.MAIN_HAND)
// Compat for people shipping unofficial CoFH APIs... -.-
def isUsable(stack: ItemStack, player: EntityLivingBase, x: Int, y: Int, z: Int): Boolean = true
def toolUsed(stack: ItemStack, player: EntityLivingBase, x: Int, y: Int, z: Int): Unit = player.swingArm(EnumHand.MAIN_HAND)
// EnderIO
def canUse(stack: ItemStack, player: EntityPlayer, pos: BlockPos): Boolean = true
def used(stack: ItemStack, player: EntityPlayer, pos: BlockPos): Unit = {}
def shouldHideFacades(stack: ItemStack, player: EntityPlayer): Boolean = false
// Mekanism
def canUseWrench(player: EntityPlayer, pos: BlockPos): Boolean = true
def canUseWrench(stack: ItemStack, player: EntityPlayer, pos: BlockPos): Boolean = true
// Project Red
def canUse(entityPlayer: EntityPlayer, itemStack: ItemStack): Boolean = true
// pre v4.7
def damageScrewdriver(world: World, player: EntityPlayer): Unit = {}
// v4.7+
def damageScrewdriver(player: EntityPlayer, stack: ItemStack): Unit = {}
// Railcraft
def canWhack(player: EntityPlayer, stack: ItemStack, pos: BlockPos): Boolean = true
def onWhack(player: EntityPlayer, stack: ItemStack, pos: BlockPos): Unit = {}
def canLink(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Boolean = false
def onLink(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Unit = {}
def canBoost(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Boolean = false
def onBoost(player: EntityPlayer, stack: ItemStack, cart: EntityMinecart): Unit = {}
// IndustrialCraft 2
def canBeStoredInToolbox(stack: ItemStack): Boolean = true
}

View File

@ -1,90 +1,13 @@
package li.cil.oc.common.item.traits
import ic2.api.item.IElectricItemManager
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.asm.Injectable
import li.cil.oc.integration.Mods
import li.cil.oc.integration.ic2.ElectricItemManager
import li.cil.oc.integration.util.Power
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.Optional
@Injectable.InterfaceList(Array(
// new Injectable.Interface(value = "appeng.api.implementations.items.IAEItemPowerStorage", modid = Mods.IDs.AppliedEnergistics2),
new Injectable.Interface(value = "cofh.api.energy.IEnergyContainerItem", modid = Mods.IDs.CoFHEnergy),
new Injectable.Interface(value = "ic2.api.item.ISpecialElectricItem", modid = Mods.IDs.IndustrialCraft2),
new Injectable.Interface(value = "mekanism.api.energy.IEnergizedItem", modid = Mods.IDs.Mekanism)
))
// TODO Forge power capabilities.
trait Chargeable extends api.driver.item.Chargeable {
def maxCharge(stack: ItemStack): Double
def getCharge(stack: ItemStack): Double
def setCharge(stack: ItemStack, amount: Double): Unit
// Applied Energistics 2
/* TODO AE2
def getAECurrentPower(stack: ItemStack): Double =
Power.toAE(getCharge(stack))
def getAEMaxPower(stack: ItemStack): Double =
Power.toAE(maxCharge(stack))
def injectAEPower(stack: ItemStack, value: Double): Double =
Power.toAE(charge(stack, Power.fromAE(value), false))
def extractAEPower(stack: ItemStack, value: Double): Double =
value - Power.toAE(charge(stack, Power.fromAE(-value), false))
@Optional.Method(modid = Mods.IDs.AppliedEnergistics2)
def getPowerFlow(stack: ItemStack): AccessRestriction = AccessRestriction.WRITE
*/
// IndustrialCraft 2
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getManager(stack: ItemStack): IElectricItemManager = ElectricItemManager
def getMaxCharge(stack: ItemStack): Double = Power.toEU(maxCharge(stack))
def getTransferLimit(stack: ItemStack): Double = Power.toEU(Settings.get.chargeRateTablet)
def getTier(stack: ItemStack): Int = 1
def canProvideEnergy(stack: ItemStack): Boolean = false
// Mekanism
def getEnergy(stack: ItemStack): Double =
Power.toJoules(getCharge(stack))
def setEnergy(stack: ItemStack, amount: Double): Unit =
setCharge(stack, Power.fromJoules(amount))
def getMaxEnergy(stack: ItemStack): Double =
Power.toJoules(maxCharge(stack))
def canSend(stack: ItemStack): Boolean = false
def canReceive(stack: ItemStack): Boolean = true
def isMetadataSpecific(stack: ItemStack): Boolean = false
def getMaxTransfer(stack: ItemStack): Double =
Power.toJoules(Settings.get.chargeRateTablet)
// Redstone Flux
def getEnergyStored(stack: ItemStack): Int =
Power.toRF(getCharge(stack))
def getMaxEnergyStored(stack: ItemStack): Int =
Power.toRF(maxCharge(stack))
def receiveEnergy(stack: ItemStack, maxReceive: Int, simulate: Boolean): Int =
maxReceive - Power.toRF(charge(stack, Power.fromRF(maxReceive), simulate))
def extractEnergy(stack: ItemStack, maxExtract: Int, simulate: Boolean): Int =
maxExtract - Power.toRF(charge(stack, Power.fromRF(-maxExtract), simulate))
}

View File

@ -61,7 +61,6 @@ object ExtendedRecipe {
}
if (api.Items.get(craftedStack) == linkedCard) {
if (weAreBeingCalledFromAppliedEnergistics2) return disabled.copy()
if (SideTracker.isServer) {
Option(api.Driver.driverFor(craftedStack)).foreach(driver => {
val nbt = driver.dataTag(craftedStack)
@ -206,8 +205,6 @@ object ExtendedRecipe {
}
}
private def weAreBeingCalledFromAppliedEnergistics2 = Mods.AppliedEnergistics2.isAvailable && new Exception().getStackTrace.exists(_.getClassName == "appeng.container.implementations.ContainerPatternTerm")
private trait ItemDataWrapper {
def components: Array[ItemStack]

View File

@ -6,6 +6,7 @@ import li.cil.oc.integration.util.Wrench
import net.minecraft.inventory.InventoryCrafting
import net.minecraft.item.ItemStack
import net.minecraft.item.crafting.IRecipe
import net.minecraft.util.NonNullList
import net.minecraft.world.World
class LootDiskCyclingRecipe extends IRecipe {
@ -34,12 +35,12 @@ class LootDiskCyclingRecipe extends IRecipe {
override def getRecipeOutput: ItemStack = null
override def getRemainingItems(crafting: InventoryCrafting): Array[ItemStack] = {
val result = new Array[ItemStack](crafting.getSizeInventory)
override def getRemainingItems(crafting: InventoryCrafting): NonNullList[ItemStack] = {
val result = NonNullList.withSize[ItemStack](crafting.getSizeInventory, ItemStack.EMPTY)
for (slot <- 0 until crafting.getSizeInventory) {
val stack = crafting.getStackInSlot(slot)
if (Wrench.isWrench(stack)) {
result(slot) = stack.copy()
result.set(slot, stack.copy())
stack.setCount(0)
}
}

View File

@ -52,11 +52,11 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra
super.setSideOpen(side, value)
if (isServer) {
ServerPacketSender.sendAdapterState(this)
world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
world.notifyNeighborsOfStateChange(getPos, getBlockType, false)
getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false)
neighborChanged(side)
} else {
world.notifyBlockUpdate(getPos, world.getBlockState(getPos), world.getBlockState(getPos), 3)
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}
@ -80,7 +80,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra
def neighborChanged(d: EnumFacing) {
if (node != null && node.network != null) {
val blockPos = getPos.offset(d)
world.getTileEntity(blockPos) match {
getWorld.getTileEntity(blockPos) match {
case env: traits.Environment =>
// Don't provide adaption for our stuffs. This is mostly to avoid
// cables and other non-functional stuff popping up in the adapter
@ -88,7 +88,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra
// but the only 'downside' is that it can't be used to manipulate
// inventories, which I actually consider a plus :P
case _ =>
Option(api.Driver.driverFor(world, blockPos, d)) match {
Option(api.Driver.driverFor(getWorld, blockPos, d)) match {
case Some(newDriver) if isSideOpen(d) => blocks(d.ordinal()) match {
case Some((oldEnvironment, driver)) =>
if (newDriver != driver) {
@ -99,7 +99,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra
node.disconnect(oldEnvironment.node)
// Then rebuild - if we have something.
val environment = newDriver.createEnvironment(world, blockPos, d)
val environment = newDriver.createEnvironment(getWorld, blockPos, d)
if (environment != null) {
blocks(d.ordinal()) = Some((environment, newDriver))
if (environment.canUpdate) {
@ -114,7 +114,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra
return
}
// A challenger appears. Maybe.
val environment = newDriver.createEnvironment(world, blockPos, d)
val environment = newDriver.createEnvironment(getWorld, blockPos, d)
if (environment != null) {
blocks(d.ordinal()) = Some((environment, newDriver))
if (environment.canUpdate) {

View File

@ -123,7 +123,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
override def updateEntity() {
super.updateEntity()
if (output.isDefined && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (output.isDefined && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
val want = math.max(1, math.min(requiredEnergy, Settings.get.assemblerTickAmount * Settings.get.tickFrequency))
val have = want + (if (Settings.get.ignorePower) 0 else node.changeBuffer(-want))
requiredEnergy -= have

View File

@ -35,10 +35,10 @@ class Cable extends traits.Environment with traits.NotAnalyzable with traits.Imm
override protected def onColorChanged() {
super.onColorChanged()
if (world != null && isServer) {
if (getWorld != null && isServer) {
api.Network.joinOrCreateNetwork(this)
}
}
override def getRenderBoundingBox = common.block.Cable.bounds(world, getPos).offset(x, y, z)
override def getRenderBoundingBox = common.block.Cable.bounds(getWorld, getPos).offset(x, y, z)
}

View File

@ -37,7 +37,7 @@ class Capacitor extends traits.Environment with DeviceInfo {
super.dispose()
if (isServer) {
indirectNeighbors.map(coordinate => {
if (world.isBlockLoaded(coordinate)) Option(world.getTileEntity(coordinate))
if (getWorld.isBlockLoaded(coordinate)) Option(getWorld.getTileEntity(coordinate))
else None
}).collect {
case Some(capacitor: Capacitor) => capacitor.recomputeCapacity()
@ -59,12 +59,12 @@ class Capacitor extends traits.Environment with DeviceInfo {
Settings.get.bufferCapacitor +
Settings.get.bufferCapacitorAdjacencyBonus * EnumFacing.values.count(side => {
val blockPos = getPos.offset(side)
world.isBlockLoaded(blockPos) && (world.getTileEntity(blockPos) match {
getWorld.isBlockLoaded(blockPos) && (getWorld.getTileEntity(blockPos) match {
case capacitor: Capacitor => true
case _ => false
})
}) +
Settings.get.bufferCapacitorAdjacencyBonus / 2 * indirectNeighbors.count(blockPos => world.isBlockLoaded(blockPos) && (world.getTileEntity(blockPos) match {
Settings.get.bufferCapacitorAdjacencyBonus / 2 * indirectNeighbors.count(blockPos => getWorld.isBlockLoaded(blockPos) && (getWorld.getTileEntity(blockPos) match {
case capacitor: Capacitor =>
if (updateSecondGradeNeighbors) {
capacitor.recomputeCapacity()

View File

@ -62,7 +62,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
// ----------------------------------------------------------------------- //
override def updateEntity() {
if (isServer && isCreative && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (isServer && isCreative && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
// Creative case, make it generate power.
node.asInstanceOf[Connector].changeBuffer(Double.PositiveInfinity)
}
@ -74,7 +74,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
override protected def onRunningChanged(): Unit = {
super.onRunningChanged()
getBlockType match {
case block: common.block.Case => world.setBlockState(getPos, world.getBlockState(getPos).withProperty(PropertyRunning.Running, Boolean.box(isRunning)))
case block: common.block.Case => getWorld.setBlockState(getPos, getWorld.getBlockState(getPos).withProperty(PropertyRunning.Running, Boolean.box(isRunning)))
case _ =>
}
}

View File

@ -82,11 +82,11 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
super.updateEntity()
// Offset by hashcode to avoid all chargers ticking at the same time.
if ((world.getWorldInfo.getWorldTotalTime + math.abs(hashCode())) % 20 == 0) {
if ((getWorld.getWorldInfo.getWorldTotalTime + math.abs(hashCode())) % 20 == 0) {
updateConnectors()
}
if (isServer && world.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
if (isServer && getWorld.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) {
var canCharge = Settings.get.ignorePower
// Charging of external devices.
@ -121,15 +121,15 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
}
}
if (isClient && chargeSpeed > 0 && hasPower && world.getWorldInfo.getWorldTotalTime % 10 == 0) {
if (isClient && chargeSpeed > 0 && hasPower && getWorld.getWorldInfo.getWorldTotalTime % 10 == 0) {
connectors.foreach(connector => {
val position = connector.pos
val theta = world.rand.nextDouble * Math.PI
val phi = world.rand.nextDouble * Math.PI * 2
val theta = getWorld.rand.nextDouble * Math.PI
val phi = getWorld.rand.nextDouble * Math.PI * 2
val dx = 0.45 * Math.sin(theta) * Math.cos(phi)
val dy = 0.45 * Math.sin(theta) * Math.sin(phi)
val dz = 0.45 * Math.cos(theta)
world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, position.xCoord + dx, position.yCoord + dz, position.zCoord + dy, 0, 0, 0)
getWorld.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, position.xCoord + dx, position.yCoord + dz, position.zCoord + dy, 0, 0, 0)
})
}
}
@ -222,17 +222,17 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
def updateConnectors() {
val robots = EnumFacing.values.map(side => {
val blockPos = BlockPosition(this).offset(side)
if (world.blockExists(blockPos)) Option(world.getTileEntity(blockPos))
if (getWorld.blockExists(blockPos)) Option(getWorld.getTileEntity(blockPos))
else None
}).collect {
case Some(t: RobotProxy) => new RobotChargeable(t.robot)
}
val bounds = BlockPosition(this).bounds.expand(1, 1, 1)
val drones = world.getEntitiesWithinAABB(classOf[Drone], bounds).collect {
val drones = getWorld.getEntitiesWithinAABB(classOf[Drone], bounds).collect {
case drone: Drone => new DroneChargeable(drone)
}
val players = world.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect {
val players = getWorld.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect {
case player: EntityPlayer if api.Nanomachines.hasController(player) => new PlayerChargeable(player)
}
@ -242,7 +242,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
if (connectors.size != newConnectors.length || (connectors.nonEmpty && (connectors -- newConnectors).nonEmpty)) {
connectors.clear()
connectors ++= newConnectors
world.notifyNeighborsOfStateChange(getPos, getBlockType, false)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false)
}
}

View File

@ -46,7 +46,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
private def setActive(value: Boolean) = if (value != isActive) {
isActive = value
ServerPacketSender.sendDisassemblerActive(this, isActive)
world.notifyNeighborsOfStateChange(getPos, getBlockType, true)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, true)
}
private final lazy val deviceInfo = Map(
@ -77,7 +77,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
override def updateEntity() {
super.updateEntity()
if (isServer && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (isServer && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (queue.isEmpty) {
val instant = disassembleNextInstantly // Is reset via decrStackSize
disassemble(decrStackSize(0, 1), instant)
@ -95,7 +95,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
while (buffer >= Settings.get.disassemblerItemCost && queue.nonEmpty) {
buffer -= Settings.get.disassemblerItemCost
val stack = queue.remove(0)
if (disassembleNextInstantly || world.rand.nextDouble >= Settings.get.disassemblerBreakChance) {
if (disassembleNextInstantly || getWorld.rand.nextDouble >= Settings.get.disassemblerBreakChance) {
drop(stack)
}
}
@ -184,13 +184,13 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = {
super.setInventorySlotContents(slot, stack)
if (!world.isRemote) {
if (!getWorld.isRemote) {
disassembleNextInstantly = false
}
}
override def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit = {
if (!world.isRemote) {
if (!getWorld.isRemote) {
disassembleNextInstantly = stack != null && slot == 0 && player.capabilities.isCreativeMode
}
}

View File

@ -3,16 +3,15 @@ package li.cil.oc.common.tileentity
import java.util
import li.cil.oc._
import li.cil.oc.api.driver.DeviceInfo
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
import li.cil.oc.api.driver.DeviceInfo
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.Analyzable
import li.cil.oc.api.network._
import li.cil.oc.common.SaveHandler
import li.cil.oc.integration.util.Waila
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound
@ -407,7 +406,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
ServerPacketSender.sendHologramValues(this)
resetDirtyFlag()
}
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (litRatio < 0) this.synchronized {
litRatio = 0
for (i <- volume.indices) {
@ -440,7 +439,8 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
val cx = x + 0.5
val cy = y + 0.5
val cz = z + 0.5
val sh = width / 16 * scale * Sqrt2 // overscale to take into account 45 degree rotation
val sh = width / 16 * scale * Sqrt2
// overscale to take into account 45 degree rotation
val sv = height / 16 * scale * Sqrt2
new AxisAlignedBB(
cx + (-0.5 + translation.xCoord) * sh,
@ -454,6 +454,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
// ----------------------------------------------------------------------- //
private def dataPath = node.address + "_data"
private final val TierTag = Settings.namespace + "tier"
private final val VolumeTag = "volume"
private final val ColorsTag = "colors"
@ -495,12 +496,10 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
override def writeToNBTForServer(nbt: NBTTagCompound) = this.synchronized {
nbt.setByte(TierTag, tier.toByte)
super.writeToNBTForServer(nbt)
if (!Waila.isSavingForTooltip) {
SaveHandler.scheduleSave(world, x, z, nbt, dataPath, tag => {
tag.setIntArray(VolumeTag, volume)
tag.setIntArray(ColorsTag, colors.map(convertColor))
})
}
SaveHandler.scheduleSave(getWorld, x, z, nbt, dataPath, tag => {
tag.setIntArray(VolumeTag, volume)
tag.setIntArray(ColorsTag, colors.map(convertColor))
})
nbt.setDouble(ScaleTag, scale)
nbt.setDouble(OffsetXTag, translation.xCoord)
nbt.setDouble(OffsetYTag, translation.yCoord)

View File

@ -130,7 +130,7 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
super.updateEntity()
// Pump energy into the internal network.
if (isServer && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (isServer && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
for (side <- EnumFacing.values if side != facing) {
sidedNode(side) match {
case connector: Connector =>

View File

@ -48,11 +48,11 @@ class MotionSensor extends traits.Environment with traits.Tickable with DeviceIn
override def updateEntity() {
super.updateEntity()
if (isServer && world.getTotalWorldTime % 10 == 0) {
if (isServer && getWorld.getTotalWorldTime % 10 == 0) {
// Get a list of all living entities we could possibly detect, using a rough
// bounding box check, then refining it using the actual distance and an
// actual visibility check.
val entities = world.getEntitiesWithinAABB(classOf[EntityLivingBase], sensorBounds)
val entities = getWorld.getEntitiesWithinAABB(classOf[EntityLivingBase], sensorBounds)
.filter(entity => entity.isEntityAlive && isInRange(entity) && isVisible(entity))
.toSet
// Get rid of all tracked entities that are no longer visible.
@ -98,7 +98,7 @@ class MotionSensor extends traits.Environment with traits.Tickable with DeviceIn
if (entity.posY > y + 1) oy += 0.75
if (entity.posZ < z) oz -= 0.75
if (entity.posZ > z + 1) oz += 0.75
world.rayTraceBlocks(new Vec3d(ox, oy, oz), target) == null
getWorld.rayTraceBlocks(new Vec3d(ox, oy, oz), target) == null
}
private def sendSignal(entity: EntityLivingBase) {

View File

@ -28,11 +28,11 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R
node.remove()
api.Network.joinOrCreateNetwork(this)
ServerPacketSender.sendNetSplitterState(this)
world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
world.notifyNeighborsOfStateChange(getPos, getBlockType, false)
getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false)
}
else {
world.notifyBlockUpdate(getPos, world.getBlockState(getPos), world.getBlockState(getPos), 3)
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}
@ -61,10 +61,10 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R
node.remove()
api.Network.joinOrCreateNetwork(this)
ServerPacketSender.sendNetSplitterState(this)
world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f)
}
else {
world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}
}

View File

@ -194,7 +194,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
texture, tint)
isActive = false // Needs committing.
world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
result(true)
}

View File

@ -316,7 +316,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance
ServerPacketSender.sendRackInventory(this)
}
else {
world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}
@ -365,7 +365,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance
hasChanged(slot) = false
lastData(slot) = mountable.getData
ServerPacketSender.sendRackMountableData(this, slot)
world.notifyNeighborsOfStateChange(getPos, getBlockType, false)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false)
// These are working state dependent, so recompute them.
isOutputEnabled = hasRedstoneCard
}

View File

@ -120,16 +120,6 @@ class Relay extends traits.SwitchLike with traits.ComponentInventory with traits
}
}
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
if (Mods.ComputerCraft.isAvailable) {
packet.data.headOption match {
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
}
}
super.tryEnqueuePacket(sourceSide, packet)
}
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet): Unit = {
super.relayPacket(sourceSide, packet)

View File

@ -42,7 +42,10 @@ import net.minecraft.util.SoundCategory
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.fluids._
import net.minecraftforge.fluids.capability.CapabilityFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
@ -65,8 +68,17 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
machine.setCostPerTick(Settings.get.robotCost)
}
// ----------------------------------------------------------------------- //
override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
capability.cast(this.asInstanceOf[T])
else
super.getCapability(capability, facing)
}
override def tier = info.tier
def isCreative = tier == Tier.Four
@ -96,7 +108,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
override def setSelectedSlot(index: Int): Unit = {
selectedSlot = index max 0 min mainInventory.getSizeInventory - 1
if (world != null) {
if (getWorld != null) {
ServerPacketSender.sendRobotSelectedSlotChange(this)
}
}
@ -189,7 +201,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
def move(direction: EnumFacing): Boolean = {
val oldPosition = getPos
val newPosition = oldPosition.offset(direction)
if (!world.isBlockLoaded(newPosition)) {
if (!getWorld.isBlockLoaded(newPosition)) {
return false // Don't fall off the earth.
}
@ -201,8 +213,8 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
val blockRobotProxy = api.Items.get(Constants.BlockName.Robot).block.asInstanceOf[common.block.RobotProxy]
val blockRobotAfterImage = api.Items.get(Constants.BlockName.RobotAfterimage).block.asInstanceOf[common.block.RobotAfterimage]
val wasAir = world.isAirBlock(newPosition)
val state = world.getBlockState(newPosition)
val wasAir = getWorld.isAirBlock(newPosition)
val state = getWorld.getBlockState(newPosition)
val block = state.getBlock
val metadata = block.getMetaFromState(state)
try {
@ -214,16 +226,16 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
// worked before the client is notified so that we can use the same trick on
// the client by sending a corresponding packet. This also saves us from
// having to send the complete state again (e.g. screen buffer) each move.
world.setBlockToAir(newPosition)
getWorld.setBlockToAir(newPosition)
// In some cases (though I couldn't quite figure out which one) setBlock
// will return true, even though the block was not created / adjusted.
val created = world.setBlockState(newPosition, world.getBlockState(oldPosition), 1) &&
world.getTileEntity(newPosition) == proxy
val created = getWorld.setBlockState(newPosition, getWorld.getBlockState(oldPosition), 1) &&
getWorld.getTileEntity(newPosition) == proxy
if (created) {
assert(getPos == newPosition)
world.setBlockState(oldPosition, net.minecraft.init.Blocks.AIR.getDefaultState, 1)
world.setBlockState(oldPosition, blockRobotAfterImage.getDefaultState, 1)
assert(world.getBlockState(oldPosition).getBlock == blockRobotAfterImage)
getWorld.setBlockState(oldPosition, net.minecraft.init.Blocks.AIR.getDefaultState, 1)
getWorld.setBlockState(oldPosition, blockRobotAfterImage.getDefaultState, 1)
assert(getWorld.getBlockState(oldPosition).getBlock == blockRobotAfterImage)
// Here instead of Lua callback so that it gets called on client, too.
val moveTicks = math.max((Settings.get.moveDelay * 20).toInt, 1)
setAnimateMove(oldPosition, moveTicks)
@ -239,24 +251,24 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
if (FluidRegistry.lookupFluidForBlock(block) == null &&
!block.isInstanceOf[BlockFluidBase] &&
!block.isInstanceOf[BlockLiquid]) {
world.playEvent(2001, newPosition, Block.getIdFromBlock(block) + (metadata << 12))
getWorld.playEvent(2001, newPosition, Block.getIdFromBlock(block) + (metadata << 12))
}
else {
val sx = newPosition.getX + 0.5
val sy = newPosition.getY + 0.5
val sz = newPosition.getZ + 0.5
world.playSound(sx, sy, sz, SoundEvents.BLOCK_WATER_AMBIENT, SoundCategory.BLOCKS,
world.rand.nextFloat * 0.25f + 0.75f, world.rand.nextFloat * 1.0f + 0.5f, false)
getWorld.playSound(sx, sy, sz, SoundEvents.BLOCK_WATER_AMBIENT, SoundCategory.BLOCKS,
getWorld.rand.nextFloat * 0.25f + 0.75f, getWorld.rand.nextFloat * 1.0f + 0.5f, false)
}
}
}
world.notifyBlockUpdate(oldPosition)
world.notifyBlockUpdate(newPosition)
getWorld.notifyBlockUpdate(oldPosition)
getWorld.notifyBlockUpdate(newPosition)
}
assert(!isInvalid)
}
else {
world.setBlockToAir(newPosition)
getWorld.setBlockToAir(newPosition)
}
created
}
@ -313,8 +325,8 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
override def shouldRenderInPass(pass: Int) = true
override def getRenderBoundingBox =
if (getBlockType != null && world != null)
getBlockType.getCollisionBoundingBox(world.getBlockState(getPos), world, getPos).expand(0.5, 0.5, 0.5).offset(getPos)
if (getBlockType != null && getWorld != null)
getBlockType.getCollisionBoundingBox(getWorld.getBlockState(getPos), getWorld, getPos).expand(0.5, 0.5, 0.5).offset(getPos)
else
new AxisAlignedBB(0, 0, 0, 1, 1, 1).offset(getPos)
@ -331,7 +343,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
}
super.updateEntity()
if (isServer) {
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (info.tier == 3) {
bot.node.changeBuffer(Double.PositiveInfinity)
}
@ -355,7 +367,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
for (slot <- 0 until equipmentInventory.getSizeInventory + mainInventory.getSizeInventory) {
getStackInSlot(slot) match {
case stack: ItemStack => try stack.updateAnimation(world, if (!world.isRemote) player_ else null, slot, slot == 0) catch {
case stack: ItemStack => try stack.updateAnimation(getWorld, if (!getWorld.isRemote) player_ else null, slot, slot == 0) catch {
case ignored: NullPointerException => // Client side item updates that need a player instance...
}
case _ =>
@ -550,7 +562,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
}
if (isComponentSlot(slot, stack)) {
super.onItemAdded(slot, stack)
world.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false)
getWorld.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false)
}
if (isInventorySlot(slot)) {
machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1))
@ -576,7 +588,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1))
}
if (isComponentSlot(slot, stack)) {
world.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false)
getWorld.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false)
}
}
}
@ -692,7 +704,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
components(slot) = None
}
getSizeInventory = realSize + componentCount
if (world != null && isServer) {
if (getWorld != null && isServer) {
for (stack <- removed) {
player().inventory.addItemStackToInventory(stack)
spawnStackInWorld(stack, Option(facing))
@ -730,7 +742,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
}
else super.setInventorySlotContents(slot, stack)
}
else if (stack != null && stack.getCount > 0 && !world.isRemote) spawnStackInWorld(stack, Option(EnumFacing.UP))
else if (stack != null && stack.getCount > 0 && !getWorld.isRemote) spawnStackInWorld(stack, Option(EnumFacing.UP))
}
override def isUsableByPlayer(player: EntityPlayer) =
@ -757,14 +769,14 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
// ----------------------------------------------------------------------- //
override def dropSlot(slot: Int, count: Int, direction: Option[EnumFacing]) =
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), mainInventory, slot, count, direction)
InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), mainInventory, slot, count, direction)
override def dropAllSlots() = {
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), this, 0, Int.MaxValue)
InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, 0, Int.MaxValue)
for (slot <- containerSlots) {
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), this, slot, Int.MaxValue)
InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, slot, Int.MaxValue)
}
InventoryUtils.dropAllSlots(BlockPosition(x, y, z, world), mainInventory)
InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getWorld), mainInventory)
}
// ----------------------------------------------------------------------- //

View File

@ -6,6 +6,9 @@ import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.fluids.capability.CapabilityFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
@ -21,13 +24,18 @@ import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraftforge.fluids.Fluid
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.IFluidHandler
class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInformation with traits.RotatableTile with ISidedInventory with IFluidHandler with internal.Robot {
def this() = this(new Robot())
// ----------------------------------------------------------------------- //
override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
capability.cast(this.asInstanceOf[T])
else super.getCapability(capability, facing)
}
override val node = api.Network.newNode(this, Visibility.Network).
withComponent("robot", Visibility.Neighbors).
create()
@ -112,7 +120,7 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo
super.validate()
val firstProxy = robot.proxy == null
robot.proxy = this
robot.setWorld(world)
robot.setWorld(getWorld)
robot.setPos(getPos)
if (firstProxy) {
robot.validate()

View File

@ -66,7 +66,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
override def canConnect(side: EnumFacing) = side != facing
// Allow connections from front for keyboards, and keyboards only...
override def sidedNode(side: EnumFacing) = if (side != facing || (world.isBlockLoaded(getPos.offset(side)) && world.getTileEntity(getPos.offset(side)).isInstanceOf[Keyboard])) node else null
override def sidedNode(side: EnumFacing) = if (side != facing || (getWorld.isBlockLoaded(getPos.offset(side)) && getWorld.getTileEntity(getPos.offset(side)).isInstanceOf[Keyboard])) node else null
// ----------------------------------------------------------------------- //
@ -81,7 +81,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
def hasKeyboard = screens.exists(screen =>
EnumFacing.values.map(side => (side, {
val blockPos = BlockPosition(screen).offset(side)
if (world.blockExists(blockPos)) world.getTileEntity(blockPos)
if (getWorld.blockExists(blockPos)) getWorld.getTileEntity(blockPos)
else null
})).exists {
case (side, keyboard: Keyboard) => keyboard.hasNodeOnSide(side.getOpposite)
@ -113,7 +113,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
if (ax <= border || ay <= border || ax >= width - border || ay >= height - border) {
return (false, None)
}
if (!world.isRemote) return (true, None)
if (!getWorld.isRemote) return (true, None)
val (iw, ih) = (width - border * 2, height - border * 2)
val (rx, ry) = ((ax - border) / iw, (ay - border) / ih)
@ -197,7 +197,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
val lpos = project(current)
def tryQueue(dx: Int, dy: Int) {
val npos = unproject(lpos.x + dx, lpos.y + dy, lpos.z)
if (world.blockExists(npos)) world.getTileEntity(npos) match {
if (getWorld.blockExists(npos)) getWorld.getTileEntity(npos) match {
case s: Screen if s.pitch == pitch && s.yaw == yaw && pending.add(s) => queue += s
case _ => // Ignore.
}
@ -219,7 +219,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
}
if (isClient) {
val bounds = current.origin.getRenderBoundingBox
world.markBlockRangeForRenderUpdate(bounds.minX.toInt, bounds.minY.toInt, bounds.minZ.toInt,
getWorld.markBlockRangeForRenderUpdate(bounds.minX.toInt, bounds.minY.toInt, bounds.minZ.toInt,
bounds.maxX.toInt, bounds.maxY.toInt, bounds.maxZ.toInt)
}
}
@ -373,7 +373,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
val opos = project(origin)
def tryMergeTowards(dx: Int, dy: Int) = {
val npos = unproject(opos.x + dx, opos.y + dy, opos.z)
world.blockExists(npos) && (world.getTileEntity(npos) match {
getWorld.blockExists(npos) && (getWorld.getTileEntity(npos) match {
case s: Screen if s.tier == tier && s.pitch == pitch && s.getColor == getColor && s.yaw == yaw && !screens.contains(s) =>
val spos = project(s.origin)
val canMergeAlongX = spos.y == opos.y && s.height == height && s.width + width <= Settings.get.maxScreenWidth

View File

@ -34,16 +34,6 @@ class Switch extends traits.SwitchLike with traits.NotAnalyzable with traits.Com
// ----------------------------------------------------------------------- //
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
if (Mods.ComputerCraft.isAvailable) {
packet.data.headOption match {
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
}
}
super.tryEnqueuePacket(sourceSide, packet)
}
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) {
super.relayPacket(sourceSide, packet)
onSwitchActivity()

View File

@ -38,13 +38,13 @@ class Waypoint extends traits.Environment with traits.Rotatable with traits.Reds
super.updateEntity()
if (isClient) {
val origin = position.toVec3.addVector(facing.getFrontOffsetX * 0.5, facing.getFrontOffsetY * 0.5, facing.getFrontOffsetZ * 0.5)
val dx = (world.rand.nextFloat() - 0.5f) * 0.8f
val dy = (world.rand.nextFloat() - 0.5f) * 0.8f
val dz = (world.rand.nextFloat() - 0.5f) * 0.8f
val vx = (world.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetX * 0.3f
val vy = (world.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetY * 0.3f - 0.5f
val vz = (world.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetZ * 0.3f
world.spawnParticle(EnumParticleTypes.PORTAL, origin.xCoord + dx, origin.yCoord + dy, origin.zCoord + dz, vx, vy, vz)
val dx = (getWorld.rand.nextFloat() - 0.5f) * 0.8f
val dy = (getWorld.rand.nextFloat() - 0.5f) * 0.8f
val dz = (getWorld.rand.nextFloat() - 0.5f) * 0.8f
val vx = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetX * 0.3f
val vy = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetY * 0.3f - 0.5f
val vz = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetZ * 0.3f
getWorld.spawnParticle(EnumParticleTypes.PORTAL, origin.xCoord + dx, origin.yCoord + dy, origin.zCoord + dz, vx, vy, vz)
}
}

View File

@ -19,16 +19,7 @@ import net.minecraft.nbt.NBTTagIntArray
import net.minecraft.util.EnumFacing
import net.minecraftforge.common.util.Constants.NBT
/* TODO MFR
import powercrystals.minefactoryreloaded.api.rednet.IRedNetNetworkContainer
*/
@Optional.InterfaceList(Array(
new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledEmitter", modid = Mods.IDs.RedLogic),
new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledUpdatable", modid = Mods.IDs.RedLogic),
new Optional.Interface(iface = "mrtjp.projectred.api.IBundledTile", modid = Mods.IDs.ProjectRedTransmission)
))
trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IBundledUpdatable with IBundledTile TODO RedLogic, Project Red, MFR */ {
trait BundledRedstoneAware extends RedstoneAware {
protected[tileentity] val _bundledInput = Array.fill(6)(Array.fill(16)(-1))
@ -91,16 +82,6 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
def bundledOutput(side: EnumFacing, color: Int, value: Int): Unit = if (value != bundledOutput(side, color)) {
_bundledOutput(toLocal(side).ordinal())(color) = value
/* TODO MFR
if (Mods.MineFactoryReloaded.isAvailable) {
val blockPos = BlockPosition(x, y, z).offset(side)
world.getBlock(blockPos) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, blockPos.x, blockPos.y, blockPos.z, side.getOpposite)
case _ =>
}
}
*/
onRedstoneOutputChanged(side)
}
@ -152,38 +133,4 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
nbt.setNewTagList(RednetInputTag, _rednetInput.view)
}
// ----------------------------------------------------------------------- //
override protected def onRedstoneOutputEnabledChanged() {
/* TODO MFR
if (Mods.MineFactoryReloaded.isAvailable) {
for (side <- EnumFacing.VALID_DIRECTIONS) {
val blockPos = BlockPosition(x, y, z).offset(side)
world.getBlock(blockPos) match {
case block: IRedNetNetworkContainer => block.updateNetwork(world, x, y, z, side.getOpposite)
case _ =>
}
}
}
*/
super.onRedstoneOutputEnabledChanged()
}
// ----------------------------------------------------------------------- //
/* TODO RedLogic
@Optional.Method(modid = Mods.IDs.RedLogic)
def getBundledCableStrength(blockFace: Int, toDirection: Int): Array[Byte] = bundledOutput(EnumFacing.getOrientation(toDirection)).map(value => math.min(math.max(value, 0), 255).toByte)
@Optional.Method(modid = Mods.IDs.RedLogic)
def onBundledInputChanged() = checkRedstoneInputChanged()
*/
// ----------------------------------------------------------------------- //
/* TODO Project Red
@Optional.Method(modid = Mods.IDs.ProjectRedTransmission)
def canConnectBundled(side: Int) = isOutputEnabled
@Optional.Method(modid = Mods.IDs.ProjectRedTransmission)
def getBundledSignal(side: Int) = bundledOutput(EnumFacing.getOrientation(side)).map(value => math.min(math.max(value, 0), 255).toByte)
*/
}

View File

@ -24,7 +24,7 @@ trait Colored extends TileEntity with internal.Colored {
override def controlsConnectivity = false
protected def onColorChanged() {
if (world != null && isServer) {
if (getWorld != null && isServer) {
PacketSender.sendColorChange(this)
}
}

View File

@ -8,7 +8,6 @@ import li.cil.oc.api
import li.cil.oc.client.Sound
import li.cil.oc.common.tileentity.RobotProxy
import li.cil.oc.integration.opencomputers.DriverRedstoneCard
import li.cil.oc.integration.util.Waila
import li.cil.oc.server.agent
import li.cil.oc.server.{PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._
@ -53,11 +52,11 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
if (value) {
hasErrored = false
}
if (world != null) {
world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
if (world.isRemote) {
if (getWorld != null) {
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
if (getWorld.isRemote) {
runSound.foreach(sound =>
if (_isRunning) Sound.startLoop(this, sound, 0.5f, 50 + world.rand.nextInt(50))
if (_isRunning) Sound.startLoop(this, sound, 0.5f, 50 + getWorld.rand.nextInt(50))
else Sound.stopLoop(this)
)
}
@ -127,7 +126,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
override def dispose(): Unit = {
super.dispose()
if (machine != null && !this.isInstanceOf[RobotProxy] && !moving) {
if (machine != null && !this.isInstanceOf[RobotProxy]) {
machine.stop()
}
}
@ -160,8 +159,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
override def writeToNBTForServer(nbt: NBTTagCompound) {
super.writeToNBTForServer(nbt)
if (machine != null) {
if (!Waila.isSavingForTooltip)
nbt.setNewCompoundTag(ComputerTag, machine.save)
nbt.setNewCompoundTag(ComputerTag, machine.save)
}
}
@ -172,7 +170,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
setRunning(nbt.getBoolean(IsRunningTag))
_users.clear()
_users ++= nbt.getTagList(UsersTag, NBT.TAG_STRING).map((tag: NBTTagString) => tag.getString)
if (_isRunning) runSound.foreach(sound => Sound.startLoop(this, sound, 0.5f, 1000 + world.rand.nextInt(2000)))
if (_isRunning) runSound.foreach(sound => Sound.startLoop(this, sound, 0.5f, 1000 + getWorld.rand.nextInt(2000)))
}
override def writeToNBTForClient(nbt: NBTTagCompound) {

View File

@ -3,29 +3,24 @@ package li.cil.oc.common.tileentity.traits
import li.cil.oc.Settings
import li.cil.oc.api.network
import li.cil.oc.api.network.Connector
import li.cil.oc.api.network.Node
import li.cil.oc.api.network.SidedEnvironment
import li.cil.oc.common.EventHandler
import li.cil.oc.common.asm.Injectable
import li.cil.oc.integration.Mods
import li.cil.oc.server.network.Network
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ExtendedWorld._
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraftforge.fml.common.Optional
@Injectable.Interface(value = "appeng.api.movable.IMovableTile", modid = Mods.IDs.AppliedEnergistics2)
trait Environment extends TileEntity with network.Environment with network.EnvironmentHost {
protected var isChangeScheduled = false
override def world = getWorld
override def xPosition = x + 0.5
override def yPosition = y + 0.5
override def zPosition = z + 0.5
override def markChanged() = if (this.isInstanceOf[Tickable]) isChangeScheduled = true else world.markChunkDirty(getPos, this)
override def markChanged() = if (this.isInstanceOf[Tickable]) isChangeScheduled = true else getWorld.markChunkDirty(getPos, this)
protected def isConnected = node != null && node.address != null && node.network != null
@ -41,7 +36,7 @@ trait Environment extends TileEntity with network.Environment with network.Envir
override def updateEntity() {
super.updateEntity()
if (isChangeScheduled) {
world.markChunkDirty(getPos, this)
getWorld.markChunkDirty(getPos, this)
isChangeScheduled = false
}
}
@ -49,34 +44,12 @@ trait Environment extends TileEntity with network.Environment with network.Envir
override def dispose() {
super.dispose()
if (isServer) {
if (moving && this.isInstanceOf[Computer]) {
this match {
case env: SidedEnvironment =>
for (side <- EnumFacing.values) {
val npos = position.offset(side)
Network.getNetworkNode(world.getTileEntity(npos), side.getOpposite) match {
case neighbor: Node if env.sidedNode(side) != null => env.sidedNode(side).disconnect(neighbor)
case _ => // No neighbor node.
}
}
case env =>
for (side <- EnumFacing.values) {
val npos = position.offset(side)
Network.getNetworkNode(world.getTileEntity(npos), side.getOpposite) match {
case neighbor: Node if env.node != null => env.node.disconnect(neighbor)
case _ => // No neighbor node.
}
}
}
}
else {
Option(node).foreach(_.remove)
this match {
case sidedEnvironment: SidedEnvironment => for (side <- EnumFacing.values) {
Option(sidedEnvironment.sidedNode(side)).foreach(_.remove())
}
case _ =>
Option(node).foreach(_.remove)
this match {
case sidedEnvironment: SidedEnvironment => for (side <- EnumFacing.values) {
Option(sidedEnvironment.sidedNode(side)).foreach(_.remove())
}
case _ =>
}
}
}
@ -121,22 +94,5 @@ trait Environment extends TileEntity with network.Environment with network.Envir
// ----------------------------------------------------------------------- //
protected var moving = false
@Optional.Method(modid = Mods.IDs.AppliedEnergistics2)
def prepareToMove(): Boolean = {
moving = true
true
}
@Optional.Method(modid = Mods.IDs.AppliedEnergistics2)
def doneMoving(): Unit = {
moving = false
Network.joinOrCreateNetwork(this)
world.notifyBlockUpdate(getPos)
}
// ----------------------------------------------------------------------- //
protected def result(args: Any*) = li.cil.oc.util.ResultWrapper.result(args: _*)
}

View File

@ -74,7 +74,7 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable {
relayCooldown = relayDelay - 1
}
}
else if (world.getTotalWorldTime % relayDelay == 0) {
else if (getWorld.getTotalWorldTime % relayDelay == 0) {
packetsPerCycleAvg += 0
}
}

View File

@ -36,11 +36,11 @@ trait Inventory extends TileEntity with inventory.Inventory {
// ----------------------------------------------------------------------- //
def dropSlot(slot: Int, count: Int = getInventoryStackLimit, direction: Option[EnumFacing] = None) =
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), this, slot, count, direction)
InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, slot, count, direction)
def dropAllSlots() =
InventoryUtils.dropAllSlots(BlockPosition(x, y, z, world), this)
InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getWorld), this)
def spawnStackInWorld(stack: ItemStack, direction: Option[EnumFacing] = None) =
InventoryUtils.spawnStackInWorld(BlockPosition(x, y, z, world), stack, direction)
InventoryUtils.spawnStackInWorld(BlockPosition(x, y, z, getWorld), stack, direction)
}

View File

@ -2,11 +2,3 @@ package li.cil.oc.common.tileentity.traits
trait PowerAcceptor
extends power.Common
// with power.AppliedEnergistics2
// with power.Factorization
// with power.Galacticraft
with power.IndustrialCraft2Experimental
// with power.IndustrialCraft2Classic
// with power.Mekanism
with power.RedstoneFlux
// with power.RotaryCraft

View File

@ -12,7 +12,7 @@ trait PowerBalancer extends PowerInformation with SidedEnvironment with Tickable
override def updateEntity() {
super.updateEntity()
if (isServer && isConnected && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
if (isServer && isConnected && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) {
val nodes = connectors
def network(connector: Connector) = if (connector != null && connector.network != null) connector.network else this
// Yeeeeah, so that just happened... it's not a beauty, but it works. This

View File

@ -19,12 +19,7 @@ import mods.immibis.redlogic.api.wiring.IWire
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
@Optional.InterfaceList(Array(
new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IConnectable", modid = Mods.IDs.RedLogic),
new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneEmitter", modid = Mods.IDs.RedLogic),
new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneUpdatable", modid = Mods.IDs.RedLogic)
))
trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmitter with IRedstoneUpdatable TODO RedLogic */ {
trait RedstoneAware extends RotationAware {
protected[tileentity] val _input = Array.fill(6)(-1)
protected[tileentity] val _output = Array.fill(6)(0)
@ -135,34 +130,19 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {}
protected def onRedstoneOutputEnabledChanged() {
if (world != null) {
world.notifyNeighborsOfStateChange(getPos, getBlockType, true)
if (getWorld != null) {
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, true)
if (isServer) ServerPacketSender.sendRedstoneState(this)
else world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
else getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}
protected def onRedstoneOutputChanged(side: EnumFacing) {
val blockPos = getPos.offset(side)
world.neighborChanged(blockPos, getBlockType, blockPos)
world.notifyNeighborsOfStateExcept(blockPos, world.getBlockState(blockPos).getBlock, side.getOpposite)
getWorld.neighborChanged(blockPos, getBlockType, blockPos)
getWorld.notifyNeighborsOfStateExcept(blockPos, getWorld.getBlockState(blockPos).getBlock, side.getOpposite)
if (isServer) ServerPacketSender.sendRedstoneState(this)
else world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
else getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
// ----------------------------------------------------------------------- //
/* TODO RedLogic
@Optional.Method(modid = Mods.IDs.RedLogic)
override def connects(wire: IWire, blockFace: Int, fromDirection: Int) = isOutputEnabled
@Optional.Method(modid = Mods.IDs.RedLogic)
override def connectsAroundCorner(wire: IWire, blockFace: Int, fromDirection: Int) = false
@Optional.Method(modid = Mods.IDs.RedLogic)
override def getEmittedSignalStrength(blockFace: Int, toDirection: Int): Short = _output(toLocal(ForgeDirection.getOrientation(toDirection)).ordinal()).toShort
@Optional.Method(modid = Mods.IDs.RedLogic)
override def onRedstoneInputChanged() = checkRedstoneInputChanged()
*/
}

View File

@ -24,8 +24,8 @@ trait Rotatable extends RotationAware with internal.Rotatable {
// Accessors
// ----------------------------------------------------------------------- //
def pitch = if (world != null && world.isBlockLoaded(getPos)) getBlockType match {
case rotatable if world.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Pitch) => world.getBlockState(getPos).getValue(PropertyRotatable.Pitch)
def pitch = if (getWorld != null && getWorld.isBlockLoaded(getPos)) getBlockType match {
case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Pitch) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Pitch)
case _ => EnumFacing.NORTH
} else null
@ -35,9 +35,9 @@ trait Rotatable extends RotationAware with internal.Rotatable {
case _ => EnumFacing.NORTH
}, yaw)
def yaw = if (world != null && world.isBlockLoaded(getPos)) getBlockType match {
case rotatable if world.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Yaw) => world.getBlockState(getPos).getValue(PropertyRotatable.Yaw)
case rotatable if world.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Facing) => world.getBlockState(getPos).getValue(PropertyRotatable.Facing)
def yaw = if (getWorld != null && getWorld.isBlockLoaded(getPos)) getBlockType match {
case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Yaw) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Yaw)
case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Facing) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Facing)
case _ => EnumFacing.SOUTH
} else null
@ -72,9 +72,9 @@ trait Rotatable extends RotationAware with internal.Rotatable {
}
def rotate(axis: EnumFacing) = {
val block = world.getBlock(position)
val block = getWorld.getBlock(position)
if (block != null) {
val valid = block.getValidRotations(world, getPos)
val valid = block.getValidRotations(getWorld, getPos)
if (valid != null && valid.contains(axis)) {
val (newPitch, newYaw) = facing.getRotation(axis) match {
case value@(EnumFacing.UP | EnumFacing.DOWN) =>
@ -110,26 +110,26 @@ trait Rotatable extends RotationAware with internal.Rotatable {
ServerPacketSender.sendRotatableState(this)
}
else {
world.notifyBlockUpdate(getPos)
getWorld.notifyBlockUpdate(getPos)
}
world.notifyNeighborsOfStateChange(getPos, getBlockType, false)
getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false)
}
// ----------------------------------------------------------------------- //
/** Updates cached translation array and sends notification to clients. */
protected def updateTranslation(): Unit = {
if (world != null) {
if (getWorld != null) {
onRotationChanged()
}
}
/** Validates new values against the allowed rotations as set in our block. */
protected def trySetPitchYaw(pitch: EnumFacing, yaw: EnumFacing) = {
val oldState = world.getBlockState(getPos)
val oldState = getWorld.getBlockState(getPos)
def setState(newState: IBlockState): Boolean = {
if (oldState.hashCode() != newState.hashCode()) {
world.setBlockState(getPos, newState)
getWorld.setBlockState(getPos, newState)
updateTranslation()
true
}

View File

@ -1,12 +1,6 @@
package li.cil.oc.common.tileentity.traits
import li.cil.oc.api
import li.cil.oc.common.asm.Injectable
import li.cil.oc.integration.Mods
import net.minecraftforge.fml.common.Optional
@Injectable.Interface(value = "buildcraft.api.tiles.IHasWork", modid = Mods.IDs.BuildCraft)
trait StateAware extends api.util.StateAware {
@Optional.Method(modid = Mods.IDs.BuildCraft)
def hasWork: Boolean = getCurrentState.contains(api.util.StateAware.State.CanWork) || getCurrentState.contains(api.util.StateAware.State.IsWorking)
}

View File

@ -18,25 +18,23 @@ import net.minecraftforge.fml.relauncher.SideOnly
trait TileEntity extends net.minecraft.tileentity.TileEntity {
private final val IsServerDataTag = Settings.namespace + "isServerData"
def world = getWorld
def x = getPos.getX
def y = getPos.getY
def z = getPos.getZ
def position = BlockPosition(x, y, z, world)
def position = BlockPosition(x, y, z, getWorld)
def isClient = !isServer
def isServer = if (world != null) !world.isRemote else SideTracker.isServer
def isServer = if (getWorld != null) !getWorld.isRemote else SideTracker.isServer
// ----------------------------------------------------------------------- //
def updateEntity() {
if (Settings.get.periodicallyForceLightUpdate && world.getTotalWorldTime % 40 == 0 && getBlockType.getLightValue(world.getBlockState(getPos), world, getPos) > 0) {
world.notifyBlockUpdate(getPos, world.getBlockState(getPos), world.getBlockState(getPos), 3)
if (Settings.get.periodicallyForceLightUpdate && getWorld.getTotalWorldTime % 40 == 0 && getBlockType.getLightValue(getWorld.getBlockState(getPos), getWorld, getPos) > 0) {
getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3)
}
}

View File

@ -1,96 +0,0 @@
package li.cil.oc.common.tileentity.traits.power
import ic2.api.energy.tile.IEnergyEmitter
import li.cil.oc.OpenComputers
import li.cil.oc.Settings
import li.cil.oc.common.EventHandler
import li.cil.oc.common.asm.Injectable
import li.cil.oc.common.tileentity.traits
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.Power
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.Optional
import net.minecraftforge.fml.common.eventhandler.Event
@Injectable.Interface(value = "ic2.api.energy.tile.IEnergySink", modid = Mods.IDs.IndustrialCraft2)
trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common with traits.Tickable {
private var conversionBuffer = 0.0
private lazy val useIndustrialCraft2Power = isServer && Mods.IndustrialCraft2.isAvailable
// ----------------------------------------------------------------------- //
override def updateEntity() {
super.updateEntity()
if (useIndustrialCraft2Power && world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
updateEnergy()
}
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
private def updateEnergy() {
tryAllSides((demand, _) => {
val result = math.min(demand, conversionBuffer)
conversionBuffer -= result
result
}, Power.fromEU, Power.toEU)
}
override def validate() {
super.validate()
if (useIndustrialCraft2Power && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this)
}
override def invalidate() {
super.invalidate()
if (useIndustrialCraft2Power && addedToIC2PowerGrid) removeFromIC2Grid()
}
override def onChunkUnload() {
super.onChunkUnload()
if (useIndustrialCraft2Power && addedToIC2PowerGrid) removeFromIC2Grid()
}
private def removeFromIC2Grid() {
try MinecraftForge.EVENT_BUS.post(Class.forName("ic2.api.energy.event.EnergyTileUnloadEvent").getConstructor(Class.forName("ic2.api.energy.tile.IEnergyTile")).newInstance(this).asInstanceOf[Event]) catch {
case t: Throwable => OpenComputers.log.warn("Error removing node from IC2 grid.", t)
}
addedToIC2PowerGrid = false
}
// ----------------------------------------------------------------------- //
override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt)
conversionBuffer = nbt.getDouble(Settings.namespace + "ic2power")
}
override def writeToNBTForServer(nbt: NBTTagCompound) {
super.writeToNBTForServer(nbt)
nbt.setDouble(Settings.namespace + "ic2power", conversionBuffer)
}
// ----------------------------------------------------------------------- //
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getSinkTier: Int = Int.MaxValue
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def acceptsEnergyFrom(emitter: IEnergyEmitter, direction: EnumFacing): Boolean = useIndustrialCraft2Power && canConnectPower(direction)
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def injectEnergy(directionFrom: EnumFacing, amount: Double, voltage: Double): Double = {
conversionBuffer += amount
0.0
}
@Optional.Method(modid = Mods.IDs.IndustrialCraft2)
def getDemandedEnergy: Double = {
if (!useIndustrialCraft2Power) 0.0
else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency)
math.min(EnumFacing.VALUES.map(globalDemand).max, Power.toEU(energyThroughput))
else 0
}
}

View File

@ -1,30 +0,0 @@
package li.cil.oc.common.tileentity.traits.power
import li.cil.oc.common.asm.Injectable
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.Power
import net.minecraft.util.EnumFacing
import net.minecraftforge.fml.common.Optional
@Injectable.Interface(value = "cofh.api.energy.IEnergyReceiver", modid = Mods.IDs.CoFHEnergy)
trait RedstoneFlux extends Common {
// IEnergyReceiver
@Optional.Method(modid = Mods.IDs.CoFHEnergy)
def receiveEnergy(from: EnumFacing, maxReceive: Int, simulate: Boolean): Int =
if (!Mods.CoFHEnergy.isAvailable) 0
else Power.toRF(tryChangeBuffer(from, Power.fromRF(maxReceive), !simulate))
// IEnergyHandler
@Optional.Method(modid = Mods.IDs.CoFHEnergy)
def getEnergyStored(from: EnumFacing): Int = Power.toRF(globalBuffer(from))
@Optional.Method(modid = Mods.IDs.CoFHEnergy)
def getMaxEnergyStored(from: EnumFacing): Int = Power.toRF(globalBufferSize(from))
// IEnergyConnection
@Optional.Method(modid = Mods.IDs.CoFHEnergy)
def canConnectEnergy(from: EnumFacing): Boolean = Mods.CoFHEnergy.isAvailable && canConnectPower(from)
}

View File

@ -30,7 +30,6 @@ object Mods {
val Proxies = Array(
integration.forestry.ModForestry,
integration.mcmp.ModMCMultiPart,
integration.tis3d.ModTIS3D,
integration.minecraft.ModMinecraft,

View File

@ -19,7 +19,7 @@ import scala.collection.convert.WrapAsJava._
object LootDiskCyclingRecipeHandler extends IRecipeHandler[LootDiskCyclingRecipe] {
override def getRecipeClass: Class[LootDiskCyclingRecipe] = classOf[LootDiskCyclingRecipe]
override def getRecipeCategoryUid: String = VanillaRecipeCategoryUid.CRAFTING
def getRecipeCategoryUid: String = VanillaRecipeCategoryUid.CRAFTING
override def getRecipeCategoryUid(recipe: LootDiskCyclingRecipe): String = getRecipeCategoryUid
@ -29,9 +29,9 @@ object LootDiskCyclingRecipeHandler extends IRecipeHandler[LootDiskCyclingRecipe
class LootDiskCyclingRecipeWrapper(val recipe: LootDiskCyclingRecipe) extends BlankRecipeWrapper with ICraftingRecipeWrapper {
override def getInputs: util.List[util.List[ItemStack]] = List(seqAsJavaList(Loot.disksForCycling), seqAsJavaList(List(api.Items.get(Constants.ItemName.Wrench).createItemStack(1))))
def getInputs: util.List[util.List[ItemStack]] = List(seqAsJavaList(Loot.disksForCycling), seqAsJavaList(List(api.Items.get(Constants.ItemName.Wrench).createItemStack(1))))
override def getOutputs: util.List[ItemStack] = Loot.disksForCycling.toList
def getOutputs: util.List[ItemStack] = Loot.disksForCycling.toList
override def getIngredients(ingredients: IIngredients): Unit = {
ingredients.setInputLists(classOf[ItemStack], getInputs)

View File

@ -1,30 +0,0 @@
package li.cil.oc.integration.mcmp
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import mcmultipart.item.PartPlacementWrapper
import mcmultipart.multipart.MultipartRegistry
import net.minecraft.client.renderer.block.model.ModelResourceLocation
import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.relauncher.Side
object MCMultiPart {
final val CableMultipartRawLocation = Settings.resourceDomain + ":" + Constants.BlockName.Cable
final val PrintMultipartRawLocation = Settings.resourceDomain + ":" + Constants.BlockName.Print
def init(): Unit = {
MultipartRegistry.registerPart(classOf[PartCable], PartFactory.PartTypeCable.toString)
MultipartRegistry.registerPart(classOf[PartPrint], PartFactory.PartTypePrint.toString)
MultipartRegistry.registerPartFactory(PartFactory, PartFactory.PartTypeCable.toString, PartFactory.PartTypePrint.toString)
MultipartRegistry.registerPartConverter(PartConverter)
MultipartRegistry.registerReversePartConverter(PartConverter)
new PartPlacementWrapper(api.Items.get(Constants.BlockName.Cable).createItemStack(1), PartFactory).register(PartFactory.PartTypeCable.toString)
new PartPlacementWrapper(api.Items.get(Constants.BlockName.Print).createItemStack(1), PartFactory).register(PartFactory.PartTypePrint.toString)
if (FMLCommonHandler.instance.getSide == Side.CLIENT) {
MCMultiPartClient.init()
}
}
}

View File

@ -1,29 +0,0 @@
package li.cil.oc.integration.mcmp
import li.cil.oc.client.renderer.block.ModelInitialization
import li.cil.oc.client.renderer.block.PrintModel
import net.minecraft.client.renderer.block.model.ModelResourceLocation
import net.minecraftforge.client.event.ModelBakeEvent
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
object MCMultiPartClient {
final val CableMultipartLocation = new ModelResourceLocation(MCMultiPart.CableMultipartRawLocation, "multipart")
final val PrintMultipartLocation = new ModelResourceLocation(MCMultiPart.PrintMultipartRawLocation, "multipart")
def init(): Unit = {
MinecraftForge.EVENT_BUS.register(this)
}
@SubscribeEvent(priority = EventPriority.LOW)
def onModelBake(e: ModelBakeEvent): Unit = {
val registry = e.getModelRegistry
// Replace default cable model with part model to properly handle connection
// rendering to multipart cables.
registry.putObject(ModelInitialization.CableBlockLocation, PartCableModel)
registry.putObject(CableMultipartLocation, PartCableModel)
registry.putObject(PrintMultipartLocation, PrintModel)
}
}

View File

@ -1,12 +0,0 @@
package li.cil.oc.integration.mcmp
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
object ModMCMultiPart extends ModProxy {
override def getMod = Mods.MCMultiPart
override def initialize(): Unit = {
MCMultiPart.init()
}
}

View File

@ -1,265 +0,0 @@
package li.cil.oc.integration.mcmp
import java.util
import com.google.common.base.Predicate
import li.cil.oc.Constants
import li.cil.oc.api
import li.cil.oc.api.internal.Colored
import li.cil.oc.api.network.Environment
import li.cil.oc.api.network.Message
import li.cil.oc.api.network.Node
import li.cil.oc.common.block.Cable
import li.cil.oc.common.block.property
import li.cil.oc.common.capabilities.Capabilities
import li.cil.oc.common.tileentity
import li.cil.oc.util.Color
import mcmultipart.capabilities.ISlottedCapabilityProvider
import mcmultipart.multipart._
import mcmultipart.raytrace.PartMOP
import net.minecraft.block.material.Material
import net.minecraft.block.state.BlockStateContainer
import net.minecraft.block.state.IBlockState
import net.minecraft.entity.Entity
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.network.PacketBuffer
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.EnumFacing
import net.minecraft.util.EnumHand
import net.minecraft.util.ResourceLocation
import net.minecraft.util.math.AxisAlignedBB
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.property.ExtendedBlockState
import net.minecraftforge.common.property.IExtendedBlockState
import scala.collection.convert.WrapAsScala._
class PartCable extends Multipart with ISlottedPart with INormallyOccludingPart with ISlottedCapabilityProvider with Environment with Colored {
final val CableDefinition = api.Items.get(Constants.BlockName.Cable)
final val CableBlock = CableDefinition.block()
val wrapped = new tileentity.Cable()
// ----------------------------------------------------------------------- //
// Environment
override def node = wrapped.node
override def onMessage(message: Message) = wrapped.onMessage(message)
override def onConnect(node: Node) = wrapped.onConnect(node)
override def onDisconnect(node: Node) = wrapped.onDisconnect(node)
// ----------------------------------------------------------------------- //
// Colored
override def getColor = wrapped.getColor
override def setColor(value: Int): Unit = {
if (value != getColor) {
wrapped.setColor(value)
if (getWorld != null && !getWorld.isRemote) {
sendUpdatePacket(true)
}
}
}
override def controlsConnectivity = wrapped.controlsConnectivity
// ----------------------------------------------------------------------- //
// ISlottedPart
override def getSlotMask: util.EnumSet[PartSlot] = util.EnumSet.of(PartSlot.CENTER)
// ----------------------------------------------------------------------- //
// IOccludingPart
override def addOcclusionBoxes(list: util.List[AxisAlignedBB]): Unit = list.add(Cable.DefaultBounds)
// ----------------------------------------------------------------------- //
// ISlottedCapabilityProvider
override def hasCapability(capability: Capability[_], slot: PartSlot, facing: EnumFacing): Boolean = {
capability == Capabilities.EnvironmentCapability && canConnect(facing)
}
override def getCapability[T](capability: Capability[T], slot: PartSlot, facing: EnumFacing): T = {
if (capability == Capabilities.EnvironmentCapability && canConnect(facing)) this.asInstanceOf[T]
else null.asInstanceOf[T]
}
override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = {
(capability == Capabilities.ColoredCapability) || super.hasCapability(capability, facing)
}
override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = {
if (capability == Capabilities.ColoredCapability) this.asInstanceOf[T]
else super.getCapability(capability, facing)
}
private def canConnect(facing: EnumFacing) = {
val self = this
val isThis = new Predicate[IMultipart] {
override def apply(input: IMultipart): Boolean = input == self
}
OcclusionHelper.slotOcclusionTest(PartSlot.getFaceSlot(facing), isThis, getContainer.getParts) &&
OcclusionHelper.occlusionTest(OcclusionHelper.boxes(Cable.CachedBounds(Cable.mask(facing))), isThis, getContainer.getParts)
}
// ----------------------------------------------------------------------- //
// IMultipart
override def addSelectionBoxes(list: util.List[AxisAlignedBB]): Unit = {
if (getWorld != null) {
list.add(Cable.bounds(getWorld, getPos))
}
}
override def addCollisionBoxes(mask: AxisAlignedBB, list: util.List[AxisAlignedBB], collidingEntity: Entity): Unit = {
if (getWorld != null) {
val bounds = Cable.bounds(getWorld, getPos)
if (bounds.intersectsWith(mask)) list.add(bounds)
}
}
override def getPickBlock(player: EntityPlayer, hit: PartMOP): ItemStack = wrapped.createItemStack()
override def getDrops: util.List[ItemStack] = util.Arrays.asList(wrapped.createItemStack())
override def getHardness(hit: PartMOP): Float = CableBlock.getBlockHardness(MultipartRegistry.getDefaultState(this).getBaseState, getWorld, getPos)
override def getMaterial: Material = CableBlock.getMaterial(MultipartRegistry.getDefaultState(this).getBaseState)
override def isToolEffective(toolType: String, level: Int): Boolean = CableBlock.isToolEffective(toolType, getWorld.getBlockState(getPos))
// ----------------------------------------------------------------------- //
override def getModelPath = new ResourceLocation(MCMultiPart.CableMultipartRawLocation)
override def createBlockState(): BlockStateContainer = new ExtendedBlockState(CableBlock, Array.empty, Array(property.PropertyTile.Tile))
override def getExtendedState(state: IBlockState): IBlockState =
state match {
case extendedState: IExtendedBlockState =>
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
extendedState.withProperty(property.PropertyTile.Tile, wrapped)
case _ => state
}
override def onPartChanged(part: IMultipart): Unit = {
super.onPartChanged(part)
if (getWorld.isRemote) {
markRenderUpdate()
} else {
// This is a bit meh... when a previously valid connection to a neighbor of
// a multipart tile becomes invalid due to a new, occluding part, we can't
// access the now occluded node anymore, so we can't just disconnect it from
// it's neighbor. So instead we get the old list of neighbor nodes and kill
// every connection for which we can't find a currently valid neighbor.
val mask = Cable.neighbors(getWorld, getPos)
val neighbors = EnumFacing.VALUES.filter(side => (mask & (1 << side.getIndex)) != 0).map(side => {
val neighborPos = getPos.offset(side)
val neighborTile = getWorld.getTileEntity(neighborPos)
if (neighborTile == null || !canConnect(side)) null
else if (neighborTile.hasCapability(Capabilities.SidedEnvironmentCapability, side.getOpposite)) {
val host = neighborTile.getCapability(Capabilities.SidedEnvironmentCapability, side.getOpposite)
if (host != null) host.sidedNode(side.getOpposite)
else null
}
else if (neighborTile.hasCapability(Capabilities.EnvironmentCapability, side.getOpposite)) {
val host = neighborTile.getCapability(Capabilities.EnvironmentCapability, side.getOpposite)
if (host != null) host.node
else null
}
else null
}).filter(_ != null).toSet
for (neighborNode <- node.neighbors.toSeq) {
if (!neighbors.contains(neighborNode)) {
node.disconnect(neighborNode)
}
}
api.Network.joinOrCreateNetwork(getWorld, getPos)
}
}
override def onAdded(): Unit = {
super.onAdded()
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
wrapped.validate()
}
override def onRemoved(): Unit = {
super.onRemoved()
wrapped.invalidate()
wrapped.setWorldObj(null)
wrapped.setPos(null)
}
override def onLoaded(): Unit = {
super.onLoaded()
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
wrapped.validate()
}
override def onUnloaded(): Unit = {
super.onUnloaded()
wrapped.onChunkUnload()
wrapped.setWorldObj(null)
wrapped.setPos(null)
}
override def onConverted(tile: TileEntity): Unit = {
super.onConverted(tile)
tile match {
case cable: tileentity.Cable =>
wrapped.setColor(cable.getColor)
case _ =>
}
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
wrapped.validate()
}
// ----------------------------------------------------------------------- //
override def onActivated(player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, hit: PartMOP): Boolean = {
if (Color.isDye(heldItem)) {
setColor(Color.rgbValues(Color.dyeColor(heldItem)))
markDirty()
if (!player.capabilities.isCreativeMode && wrapped.consumesDye) {
heldItem.splitStack(1)
}
true
}
else super.onActivated(player, hand, heldItem, hit)
}
// ----------------------------------------------------------------------- //
override def writeToNBT(tag: NBTTagCompound): NBTTagCompound = {
super.writeToNBT(tag)
wrapped.writeToNBT(tag)
tag
}
override def readFromNBT(tag: NBTTagCompound): Unit = {
super.readFromNBT(tag)
wrapped.readFromNBT(tag)
}
override def writeUpdatePacket(buf: PacketBuffer): Unit = {
super.writeUpdatePacket(buf)
buf.writeInt(getColor)
}
override def readUpdatePacket(buf: PacketBuffer): Unit = {
super.readUpdatePacket(buf)
setColor(buf.readInt())
}
}

View File

@ -1,18 +0,0 @@
package li.cil.oc.integration.mcmp
import li.cil.oc.client.renderer.block.CableModel
import li.cil.oc.util.BlockPosition
import mcmultipart.multipart.MultipartHelper
import mcmultipart.multipart.PartSlot
object PartCableModel extends CableModel {
override protected def isCable(pos: BlockPosition): Boolean = super.isCable(pos) || (pos.world match {
case Some(world) =>
val container = MultipartHelper.getPartContainer(world, pos.toBlockPos)
(container != null) && (container.getPartInSlot(PartSlot.CENTER) match {
case cable: PartCable => true
case _ => false
})
case _ => false
})
}

View File

@ -1,88 +0,0 @@
package li.cil.oc.integration.mcmp
import java.util
import java.util.Collections
import li.cil.oc.Constants
import li.cil.oc.api
import li.cil.oc.common.EventHandler
import li.cil.oc.common.tileentity.Cable
import li.cil.oc.common.tileentity.Print
import li.cil.oc.server.PacketSender
import mcmultipart.multipart.IMultipart
import mcmultipart.multipart.IMultipartContainer
import mcmultipart.multipart.IPartConverter
import mcmultipart.multipart.IReversePartConverter
import net.minecraft.block.Block
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockAccess
import scala.collection.convert.WrapAsScala._
object PartConverter extends IPartConverter with IReversePartConverter {
final lazy val CableBlock = api.Items.get(Constants.BlockName.Cable).block()
final lazy val PrintBlock = api.Items.get(Constants.BlockName.Print).block()
override def getConvertableBlocks: util.Collection[Block] = util.Arrays.asList(CableBlock, PrintBlock)
override def convertBlock(world: IBlockAccess, pos: BlockPos, simulated: Boolean): util.Collection[_ <: IMultipart] = {
world.getTileEntity(pos) match {
case tileEntity: Cable =>
val part = new PartCable()
part.setColor(tileEntity.getColor)
if (!simulated && tileEntity.node != null && part.node != null) {
// Immediately connect node to avoid short disconnect.
for (node <- tileEntity.node.neighbors) {
node.connect(part.node)
}
}
Collections.singletonList(part)
case tileEntity: Print =>
val part = new PartPrint()
val nbt = new NBTTagCompound()
tileEntity.writeToNBTForServer(nbt)
part.wrapped.readFromNBTForServer(nbt)
Collections.singletonList(part)
case _ => Collections.emptyList()
}
}
override def convertToBlock(container: IMultipartContainer): Boolean = {
val world = container.getWorldIn
val pos = container.getPosIn
val parts = container.getParts
(parts.size() == 1) && (parts.iterator().next() match {
case part: PartCable =>
val color = part.getColor
world.setBlockToAir(pos)
world.setBlockState(pos, CableBlock.getDefaultState)
world.getTileEntity(pos) match {
case tileEntity: Cable =>
tileEntity.setColor(color)
EventHandler.scheduleServer(() => PacketSender.sendColorChange(tileEntity)) // HACKS!
case _ =>
}
// Immediately connect node to avoid short disconnect.
api.Network.joinOrCreateNetwork(world, pos)
// Required to dispose the old node because invalidate isn't forwarded to parts.
// Can't use removePart because if the list is empty when this returns, MCMP
// will tell MC that the block was removed so MC will set it to air.
part.wrapped.invalidate()
true
case part: PartPrint =>
val nbt = new NBTTagCompound()
part.wrapped.writeToNBTForServer(nbt)
world.setBlockToAir(pos)
world.setBlockState(pos, PrintBlock.getDefaultState)
world.getTileEntity(pos) match {
case tileEntity: Print =>
tileEntity.readFromNBTForServer(nbt)
case _ =>
}
true
case _ =>
false
})
}
}

View File

@ -1,61 +0,0 @@
package li.cil.oc.integration.mcmp
import li.cil.oc.Constants
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.item.data.PrintData
import li.cil.oc.integration.Mods
import mcmultipart.item.IItemMultipartFactory
import mcmultipart.multipart.IMultipart
import mcmultipart.multipart.IPartFactory
import mcmultipart.multipart.MultipartHelper
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.util.EnumFacing
import net.minecraft.util.ResourceLocation
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import scala.collection.convert.WrapAsScala._
object PartFactory extends IPartFactory with IItemMultipartFactory {
final val PartTypeCable = new ResourceLocation(Mods.IDs.OpenComputers + ":" + Constants.BlockName.Cable)
final val PartTypePrint = new ResourceLocation(Mods.IDs.OpenComputers + ":" + Constants.BlockName.Print)
final lazy val CableDescriptor = api.Items.get(Constants.BlockName.Cable)
final lazy val PrintDescriptor = api.Items.get(Constants.BlockName.Print)
override def createPart(partType: ResourceLocation, client: Boolean): IMultipart = {
if (partType == PartTypeCable) new PartCable()
else if (partType == PartTypePrint) new PartPrint()
else null
}
override def createPart(world: World, pos: BlockPos, side: EnumFacing, hit: Vec3d, stack: ItemStack, player: EntityPlayer): IMultipart = {
val descriptor = api.Items.get(stack)
if (descriptor == CableDescriptor) new PartCable()
else if (descriptor == PrintDescriptor && canAddPrint(world, pos, stack)) {
val part = new PartPrint()
part.wrapped.data.load(stack)
part.wrapped.setFromEntityPitchAndYaw(player)
if (!part.wrapped.validFacings.contains(part.wrapped.pitch)) {
part.wrapped.pitch = part.wrapped.validFacings.headOption.getOrElse(EnumFacing.NORTH)
}
part.wrapped.invertRotation()
part
}
else null
}
private def canAddPrint(world: World, pos: BlockPos, stack: ItemStack): Boolean = {
val container = MultipartHelper.getPartContainer(world, pos)
container == null || {
val complexity = container.getParts.collect {
case print: PartPrint => print.wrapped.data.complexity
}.sum
val data = new PrintData(stack)
data.complexity + complexity <= Settings.get.maxPrintComplexity
}
}
}

View File

@ -1,200 +0,0 @@
package li.cil.oc.integration.mcmp
import java.util
import li.cil.oc.Constants
import li.cil.oc.api
import li.cil.oc.common.EventHandler
import li.cil.oc.common.block.property
import li.cil.oc.common.tileentity
import mcmultipart.multipart.INormallyOccludingPart
import mcmultipart.multipart.IRedstonePart
import mcmultipart.multipart.Multipart
import mcmultipart.multipart.MultipartRegistry
import mcmultipart.raytrace.PartMOP
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.block.state.BlockStateContainer
import net.minecraft.block.state.IBlockState
import net.minecraft.entity.Entity
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.network.PacketBuffer
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.BlockRenderLayer
import net.minecraft.util.EnumFacing
import net.minecraft.util.EnumHand
import net.minecraft.util.ResourceLocation
import net.minecraft.util.math.AxisAlignedBB
import net.minecraftforge.common.property.ExtendedBlockState
import net.minecraftforge.common.property.IExtendedBlockState
class PartPrint extends Multipart with INormallyOccludingPart with IRedstonePart {
final val PrintDefinition = api.Items.get(Constants.BlockName.Print)
final val PrintBlock = PrintDefinition.block()
val wrapped = new tileentity.Print(canToggle _, scheduleUpdate _, onStateChange _)
def canToggle: Boolean = getWorld != null && !getWorld.isRemote && {
val toggled = new PartPrint()
val nbt = new NBTTagCompound()
wrapped.writeToNBTForServer(nbt)
toggled.wrapped.readFromNBTForServer(nbt)
toggled.wrapped.state = !wrapped.state
getContainer.canReplacePart(this, toggled)
}
def scheduleUpdate(delay: Int): Unit = {
EventHandler.scheduleServer(() => {
if (wrapped.state) wrapped.toggleState()
if (wrapped.state) scheduleUpdate(delay)
}, delay)
}
def onStateChange(): Unit = {
notifyPartUpdate()
sendUpdatePacket(true)
}
// ----------------------------------------------------------------------- //
// IRedstonePart
override def canConnectRedstone(side: EnumFacing): Boolean = true
override def getStrongSignal(side: EnumFacing): Int = getWeakSignal(side)
override def getWeakSignal(side: EnumFacing): Int = wrapped.output(side)
// ----------------------------------------------------------------------- //
// IOccludingPart
override def addOcclusionBoxes(list: util.List[AxisAlignedBB]): Unit = wrapped.addCollisionBoxesToList(null, list)
// ----------------------------------------------------------------------- //
// IMultipart
override def addSelectionBoxes(list: util.List[AxisAlignedBB]): Unit = wrapped.addCollisionBoxesToList(null, list)
override def addCollisionBoxes(mask: AxisAlignedBB, list: util.List[AxisAlignedBB], collidingEntity: Entity): Unit = {
if (getWorld != null) {
wrapped.addCollisionBoxesToList(mask, list)
}
}
override def getLightValue: Int = wrapped.data.lightLevel
override def getPickBlock(player: EntityPlayer, hit: PartMOP): ItemStack = wrapped.data.createItemStack()
override def getDrops: util.List[ItemStack] = util.Arrays.asList(wrapped.data.createItemStack())
override def getHardness(hit: PartMOP): Float = PrintBlock.getBlockHardness(MultipartRegistry.getDefaultState(this).getBaseState, getWorld, getPos)
override def getMaterial: Material = PrintBlock.getMaterial(MultipartRegistry.getDefaultState(this).getBaseState)
override def isToolEffective(toolType: String, level: Int): Boolean = PrintBlock.isToolEffective(toolType, getWorld.getBlockState(getPos))
// ----------------------------------------------------------------------- //
override def getModelPath = new ResourceLocation(MCMultiPart.PrintMultipartRawLocation)
override def canRenderInLayer(layer: BlockRenderLayer): Boolean = layer == BlockRenderLayer.CUTOUT_MIPPED
override def createBlockState(): BlockStateContainer = new ExtendedBlockState(PrintBlock, Array.empty, Array(property.PropertyTile.Tile))
override def getExtendedState(state: IBlockState): IBlockState =
state match {
case extendedState: IExtendedBlockState =>
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
extendedState.withProperty(property.PropertyTile.Tile, wrapped)
case _ => state
}
// ----------------------------------------------------------------------- //
override def onNeighborBlockChange(block: Block): Unit = {
EnumFacing.values().foreach(wrapped.updateRedstoneInput)
}
override def onAdded(): Unit = {
super.onAdded()
initialize()
}
override def onRemoved(): Unit = {
super.onRemoved()
wrapped.invalidate()
wrapped.setWorldObj(null)
wrapped.setPos(null)
}
override def onLoaded(): Unit = {
super.onLoaded()
initialize()
}
override def onUnloaded(): Unit = {
super.onUnloaded()
wrapped.onChunkUnload()
wrapped.setWorldObj(null)
wrapped.setPos(null)
}
override def onConverted(tile: TileEntity): Unit = {
super.onConverted(tile)
tile match {
case print: tileentity.Print =>
val nbt = new NBTTagCompound()
print.writeToNBTForServer(nbt)
wrapped.readFromNBTForServer(nbt)
case _ =>
}
initialize()
}
private def initialize(): Unit = {
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
wrapped.validate()
wrapped.updateRedstone()
if (wrapped.state && wrapped.data.isButtonMode) {
scheduleUpdate(PrintBlock.tickRate(getWorld))
}
}
// ----------------------------------------------------------------------- //
override def onActivated(player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, hit: PartMOP): Boolean = {
wrapped.activate()
}
// ----------------------------------------------------------------------- //
override def writeToNBT(tag: NBTTagCompound): NBTTagCompound = {
super.writeToNBT(tag)
wrapped.writeToNBT(tag)
tag
}
override def readFromNBT(tag: NBTTagCompound): Unit = {
super.readFromNBT(tag)
wrapped.readFromNBT(tag)
}
override def writeUpdatePacket(buf: PacketBuffer): Unit = {
super.writeUpdatePacket(buf)
val nbt = new NBTTagCompound()
wrapped.writeToNBTForClient(nbt)
buf.writeNBTTagCompoundToBuffer(nbt)
}
override def readUpdatePacket(buf: PacketBuffer): Unit = {
super.readUpdatePacket(buf)
wrapped.setWorldObj(getWorld)
wrapped.setPos(getPos)
val nbt = buf.readNBTTagCompoundFromBuffer()
wrapped.readFromNBTForClient(nbt)
}
}

View File

@ -12,7 +12,6 @@ import li.cil.oc.common.item.Delegator
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.integration.util.BundledRedstone
import li.cil.oc.integration.util.WirelessRedstone
import li.cil.oc.server.component
import net.minecraft.item.ItemStack
@ -26,17 +25,12 @@ object DriverRedstoneCard extends Item with HostAware {
else {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
host match {
case redstone: BundledRedstoneAware if hasBundled =>
if (hasWireless) new component.Redstone.BundledWireless(redstone)
else new component.Redstone.Bundled(redstone)
new component.Redstone.Bundled(redstone)
case redstone: RedstoneAware =>
if (hasWireless) new component.Redstone.VanillaWireless(redstone)
else new component.Redstone.Vanilla(redstone)
case _ =>
if (hasWireless) new component.Redstone.Wireless(host)
else null
new component.Redstone.Vanilla(redstone)
case _ => null
}
}
@ -53,10 +47,8 @@ object DriverRedstoneCard extends Item with HostAware {
if (worksWith(stack)) {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
if (hasBundled) {
if (hasWireless) classOf[component.Redstone.BundledWireless]
else classOf[component.Redstone.Bundled]
classOf[component.Redstone.Bundled]
}
else {
classOf[component.Redstone.Vanilla]

View File

@ -37,7 +37,6 @@ import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.BundledRedstone
import li.cil.oc.integration.util.ItemBlacklist
import li.cil.oc.integration.util.WirelessRedstone
import li.cil.oc.server.machine.luac.LuaStateFactory
import li.cil.oc.server.machine.luac.NativeLua53Architecture
import li.cil.oc.server.network.Waypoints
@ -294,15 +293,10 @@ object ModOpenComputers extends ModProxy {
Constants.ItemName.LeashUpgrade,
Constants.ItemName.TradingUpgrade)
if (!WirelessRedstone.isAvailable) {
blacklistHost(classOf[internal.Drone], Constants.ItemName.RedstoneCardTier2)
blacklistHost(classOf[internal.Tablet], Constants.ItemName.RedstoneCardTier2)
}
// Note: kinda nasty, but we have to check for availability for extended
// redstone mods after integration init, so we have to set tier two
// redstone card availability here, after all other mods were inited.
if (BundledRedstone.isAvailable || WirelessRedstone.isAvailable) {
if (BundledRedstone.isAvailable) {
OpenComputers.log.info("Found extended redstone mods, enabling tier two redstone card.")
Delegator.subItem(api.Items.get(Constants.ItemName.RedstoneCardTier2).createItemStack(1)) match {
case Some(redstone: RedstoneCard) => redstone.showInItemList = true

View File

@ -12,7 +12,7 @@ object BundledRedstone {
def addProvider(provider: RedstoneProvider): Unit = providers += provider
def isAvailable = Mods.MineFactoryReloaded.isAvailable || providers.nonEmpty
def isAvailable = providers.nonEmpty
def computeInput(pos: BlockPosition, side: EnumFacing): Int = {
if (pos.world.get.blockExists(pos.offset(side)))

View File

@ -1,21 +0,0 @@
package li.cil.oc.integration.util
import li.cil.oc.integration.Mods
import net.minecraft.item.ItemStack
object PortalGun {
private lazy val portalGunClass = try {
Class.forName("portalgun.common.item.ItemPortalGun")
}
catch {
case _: Throwable => null
}
def isPortalGun(stack: ItemStack) =
stack != null && stack.getCount > 0 &&
Mods.PortalGun.isAvailable &&
portalGunClass != null &&
portalGunClass.isAssignableFrom(stack.getItem.getClass)
def isStandardPortalGun(stack: ItemStack) = isPortalGun(stack) && stack.getItemDamage == 0
}

View File

@ -1,10 +0,0 @@
package li.cil.oc.integration.util
import li.cil.oc.integration.Mods
object Waila {
// This is used to check if certain data actually has to be saved in
// writeToNBT calls. For some stuff we write lots of data (e.g. computer
// state), and we want to avoid that when Waila is calling us.
def isSavingForTooltip = Mods.Waila.isAvailable && new Exception().getStackTrace.exists(_.getClassName.startsWith("mcp.mobius.waila"))
}

View File

@ -1,50 +0,0 @@
package li.cil.oc.integration.util
import li.cil.oc.server.component.RedstoneWireless
import scala.collection.mutable
object WirelessRedstone {
val systems = mutable.Set.empty[WirelessRedstoneSystem]
def isAvailable = systems.nonEmpty
def addReceiver(rs: RedstoneWireless) {
systems.foreach(system => try system.addReceiver(rs) catch {
case _: Throwable => // Ignore
})
}
def removeReceiver(rs: RedstoneWireless) {
systems.foreach(system => try system.removeReceiver(rs) catch {
case _: Throwable => // Ignore
})
}
def updateOutput(rs: RedstoneWireless) {
systems.foreach(system => try system.updateOutput(rs) catch {
case _: Throwable => // Ignore
})
}
def removeTransmitter(rs: RedstoneWireless) {
systems.foreach(system => try system.removeTransmitter(rs) catch {
case _: Throwable => // Ignore
})
}
def getInput(rs: RedstoneWireless) = systems.exists(_.getInput(rs))
trait WirelessRedstoneSystem {
def addReceiver(rs: RedstoneWireless)
def removeReceiver(rs: RedstoneWireless)
def updateOutput(rs: RedstoneWireless)
def removeTransmitter(rs: RedstoneWireless)
def getInput(rs: RedstoneWireless): Boolean
}
}

View File

@ -10,7 +10,6 @@ import li.cil.oc.api.internal
import li.cil.oc.api.network.Connector
import li.cil.oc.common.EventHandler
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util.PortalGun
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.InventoryUtils
import net.minecraft.block.Block
@ -102,13 +101,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
setSize(1, 1)
{
val inventory = new Inventory(agent)
if (Mods.BattleGear2.isAvailable) {
ObfuscationReflectionHelper.setPrivateValue(classOf[EntityPlayer], this, inventory, "inventory", "field_71071_by", "bm")
}
else this.inventory = inventory
}
this.inventory = new Inventory(agent)
var facing, side = EnumFacing.SOUTH
@ -194,10 +187,8 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
}
val item = if (stack != null) stack.getItem else null
if (!PortalGun.isPortalGun(stack)) {
if (item != null && item.onItemUseFirst(this, world, pos, side, hitX, hitY, hitZ, EnumHand.MAIN_HAND) == EnumActionResult.SUCCESS) {
return ActivationType.ItemUsed
}
if (item != null && item.onItemUseFirst(this, world, pos, side, hitX, hitY, hitZ, EnumHand.MAIN_HAND) == EnumActionResult.SUCCESS) {
return ActivationType.ItemUsed
}
val state = world.getBlockState(pos)
@ -275,7 +266,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
def sizeOrDamageChanged = newStack.getCount != oldSize || newStack.getItemDamage != oldDamage
def tagChanged = (oldData == null && newStack.hasTagCompound) || (oldData != null && !newStack.hasTagCompound) ||
(oldData != null && newStack.hasTagCompound && !oldData.equals(newStack.getTagCompound))
val stackChanged = newStack != stack || (newStack != null && (sizeOrDamageChanged || tagChanged || PortalGun.isStandardPortalGun(stack)))
val stackChanged = newStack != stack || (newStack != null && (sizeOrDamageChanged || tagChanged))
if (stackChanged) {
agent.equipmentInventory.setInventorySlotContents(0, newStack)
}
@ -403,9 +394,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
}
private def isItemUseAllowed(stack: ItemStack) = stack == null || {
(Settings.get.allowUseItemsWithDuration || stack.getMaxItemUseDuration <= 0) &&
(!PortalGun.isPortalGun(stack) || PortalGun.isStandardPortalGun(stack)) &&
!stack.isItemEqual(new ItemStack(Items.LEAD))
(Settings.get.allowUseItemsWithDuration || stack.getMaxItemUseDuration <= 0) && !stack.isItemEqual(new ItemStack(Items.LEAD))
}
override def dropItem(stack: ItemStack, dropAround: Boolean, traceItem: Boolean): EntityItem =

View File

@ -46,7 +46,7 @@ import net.minecraftforge.common.util.FakePlayer
import net.minecraftforge.common.util.FakePlayerFactory
import net.minecraftforge.fluids.FluidRegistry
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.IFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fml.common.FMLCommonHandler
import net.minecraftforge.fml.common.Loader
import net.minecraftforge.fml.common.ModAPIManager
@ -129,7 +129,7 @@ class DebugCard(host: EnvironmentHost) extends prefab.ManagedEnvironment with De
@Callback(doc = """function():table -- Get a list of currently logged-in players.""")
def getPlayers(context: Context, args: Arguments): Array[AnyRef] = {
checkAccess()
result(FMLCommonHandler.instance.getMinecraftServerInstance.getAllUsernames)
result(FMLCommonHandler.instance.getMinecraftServerInstance.getOnlinePlayerNames)
}
@Callback(doc = """function():userdata -- Get the scoreboard object for the world""")
@ -799,7 +799,7 @@ object DebugCard {
val position = BlockPosition(args.checkDouble(2), args.checkDouble(3), args.checkDouble(4), world)
val side = args.checkSideAny(5)
world.getTileEntity(position) match {
case handler: IFluidHandler => result(handler.fill(side, new FluidStack(fluid, amount), true))
case handler: IFluidHandler => result(handler.fill(new FluidStack(fluid, amount), true))
case _ => result(Unit, "no tank")
}
}
@ -811,7 +811,7 @@ object DebugCard {
val position = BlockPosition(args.checkDouble(1), args.checkDouble(2), args.checkDouble(3), world)
val side = args.checkSideAny(4)
world.getTileEntity(position) match {
case handler: IFluidHandler => result(handler.drain(side, amount, true))
case handler: IFluidHandler => result(handler.drain(amount, true))
case _ => result(Unit, "no tank")
}
}

View File

@ -1,17 +1,10 @@
package li.cil.oc.server.component
import java.util
import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
import li.cil.oc.api.network.EnvironmentHost
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.server.component
import scala.collection.convert.WrapAsJava._
object Redstone {
class Vanilla(val redstone: EnvironmentHost with RedstoneAware)
@ -20,24 +13,4 @@ object Redstone {
class Bundled(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled
class Wireless(val redstone: EnvironmentHost)
extends component.RedstoneWireless
class VanillaWireless(val redstone: EnvironmentHost with RedstoneAware)
extends component.RedstoneVanilla with component.RedstoneWireless
class BundledWireless(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled with component.RedstoneWireless {
private final lazy val deviceInfo = Map(
DeviceAttribute.Class -> DeviceClass.Communication,
DeviceAttribute.Description -> "Combined redstone controller",
DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor,
DeviceAttribute.Product -> "Rx900-M",
DeviceAttribute.Capacity -> "65536",
DeviceAttribute.Width -> "16"
)
override def getDeviceInfo: util.Map[String, String] = deviceInfo
}
}

View File

@ -1,165 +0,0 @@
package li.cil.oc.server.component
/* TODO WRCBE
import codechicken.lib.vec.Vector3
import codechicken.wirelessredstone.core.WirelessReceivingDevice
import codechicken.wirelessredstone.core.WirelessTransmittingDevice
*/
import li.cil.oc.Constants
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
import li.cil.oc.Settings
import li.cil.oc.api.driver.DeviceInfo
import li.cil.oc.api.network.EnvironmentHost
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.common.EventHandler
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fml.common.Optional
import scala.collection.convert.WrapAsJava._
@Optional.InterfaceList(Array(
new Optional.Interface(iface = "codechicken.wirelessredstone.core.WirelessReceivingDevice", modid = Mods.IDs.WirelessRedstoneCBE),
new Optional.Interface(iface = "codechicken.wirelessredstone.core.WirelessTransmittingDevice", modid = Mods.IDs.WirelessRedstoneCBE)
))
trait RedstoneWireless extends RedstoneSignaller /* with WirelessReceivingDevice with WirelessTransmittingDevice TODO WRCBE */ with DeviceInfo {
def redstone: EnvironmentHost
var wirelessFrequency = 0
var wirelessInput = false
var wirelessOutput = false
// ----------------------------------------------------------------------- //
private final lazy val deviceInfo = Map(
DeviceAttribute.Class -> DeviceClass.Communication,
DeviceAttribute.Description -> "Wireless redstone controller",
DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor,
DeviceAttribute.Product -> "Rw400-M",
DeviceAttribute.Capacity -> "1",
DeviceAttribute.Width -> "1"
)
override def getDeviceInfo: java.util.Map[String, String] = deviceInfo
// ----------------------------------------------------------------------- //
@Callback(doc = """function():number -- Get the wireless redstone input.""")
def getWirelessInput(context: Context, args: Arguments): Array[AnyRef] = {
wirelessInput = util.WirelessRedstone.getInput(this)
result(wirelessInput)
}
@Callback(direct = true, doc = """function():boolean -- Get the wireless redstone output.""")
def getWirelessOutput(context: Context, args: Arguments): Array[AnyRef] = result(wirelessOutput)
@Callback(doc = """function(value:boolean):boolean -- Set the wireless redstone output.""")
def setWirelessOutput(context: Context, args: Arguments): Array[AnyRef] = {
val oldValue = wirelessOutput
val newValue = args.checkBoolean(0)
if (oldValue != newValue) {
wirelessOutput = newValue
util.WirelessRedstone.updateOutput(this)
if (Settings.get.redstoneDelay > 0)
context.pause(Settings.get.redstoneDelay)
}
result(oldValue)
}
@Callback(direct = true, doc = """function():number -- Get the currently set wireless redstone frequency.""")
def getWirelessFrequency(context: Context, args: Arguments): Array[AnyRef] = result(wirelessFrequency)
@Callback(doc = """function(frequency:number):number -- Set the wireless redstone frequency to use.""")
def setWirelessFrequency(context: Context, args: Arguments): Array[AnyRef] = {
val oldValue = wirelessFrequency
val newValue = args.checkInteger(0)
if (oldValue != newValue) {
util.WirelessRedstone.removeReceiver(this)
util.WirelessRedstone.removeTransmitter(this)
wirelessFrequency = newValue
wirelessInput = false
wirelessOutput = false
util.WirelessRedstone.addReceiver(this)
context.pause(0.5)
}
result(oldValue)
}
// ----------------------------------------------------------------------- //
/* TODO WRCBE
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def updateDevice(frequency: Int, on: Boolean) {
if (frequency == wirelessFrequency && on != wirelessInput) {
wirelessInput = on
onRedstoneChanged("wireless", if (on) 0 else 1, if (on) 1 else 0)
}
}
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getPosition = new Vector3(redstone.xPosition, redstone.yPosition, redstone.zPosition)
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getDimension = redstone.world.provider.getDimensionId
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getFreq = wirelessFrequency
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getAttachedEntity = null
*/
// ----------------------------------------------------------------------- //
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
EventHandler.scheduleWirelessRedstone(this)
}
}
override def onDisconnect(node: Node) {
super.onDisconnect(node)
if (node == this.node) {
util.WirelessRedstone.removeReceiver(this)
util.WirelessRedstone.removeTransmitter(this)
wirelessOutput = false
wirelessFrequency = 0
}
}
// ----------------------------------------------------------------------- //
private final val WirelessFrequencyTag = "wirelessFrequency"
private final val WirelessInputTag = "wirelessInput"
private final val WirelessOutputTag = "wirelessOutput"
override def load(nbt: NBTTagCompound) {
super.load(nbt)
wirelessFrequency = nbt.getInteger(WirelessFrequencyTag)
wirelessInput = nbt.getBoolean(WirelessInputTag)
wirelessOutput = nbt.getBoolean(WirelessOutputTag)
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setInteger(WirelessFrequencyTag, wirelessFrequency)
nbt.setBoolean(WirelessInputTag, wirelessInput)
nbt.setBoolean(WirelessOutputTag, wirelessOutput)
}
}

View File

@ -6,11 +6,10 @@ import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.server.component.result
import li.cil.oc.util.ExtendedArguments._
import li.cil.oc.util.FluidUtils
import li.cil.oc.util.InventoryUtils
import net.minecraft.item.ItemStack
import net.minecraftforge.fluids.FluidContainerRegistry
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.IFluidContainerItem
trait TankInventoryControl extends WorldAware with InventoryAware with TankAware {
@Callback(doc = """function([slot:number]):number -- Get the amount of fluid in the tank item in the specified slot or the selected slot.""")
@ -39,35 +38,16 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware
Option(tank.getFluidTank(selectedTank)) match {
case Some(into) => inventory.getStackInSlot(selectedSlot) match {
case stack: ItemStack =>
if (FluidContainerRegistry.isFilledContainer(stack)) {
val contents = FluidContainerRegistry.getFluidForFilledItem(stack)
val container = stack.getItem.getContainerItem(stack)
if (into.getCapacity - into.getFluidAmount < contents.amount) {
result(Unit, "tank is full")
}
else if (into.fill(contents, false) < contents.amount) {
result(Unit, "incompatible fluid")
}
else {
into.fill(contents, true)
inventory.decrStackSize(selectedSlot, 1)
InventoryUtils.insertIntoInventory(container, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots))
if (container.getCount > 0) {
InventoryUtils.spawnStackInWorld(position, container)
}
result(true, contents.amount)
}
}
else stack.getItem match {
case from: IFluidContainerItem =>
val drained = from.drain(stack, amount, false)
Option(FluidUtils.fluidHandlerOf(stack)) match {
case Some(handler) =>
val drained = handler.drain(amount, false)
val transferred = into.fill(drained, true)
if (transferred > 0) {
from.drain(stack, transferred, true)
handler.drain(transferred, true)
result(true, transferred)
}
else result(Unit, "incompatible or no fluid")
case _ => result(Unit, "item is empty or not a fluid container")
case _ => result(Unit, "item is not a fluid container")
}
case _ => result(Unit, "nothing selected")
}
@ -81,33 +61,16 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware
Option(tank.getFluidTank(selectedTank)) match {
case Some(from) => inventory.getStackInSlot(selectedSlot) match {
case stack: ItemStack =>
if (FluidContainerRegistry.isEmptyContainer(stack)) {
val drained = from.drain(amount, false)
val filled = FluidContainerRegistry.fillFluidContainer(drained, stack)
if (filled == null) {
result(Unit, "tank is empty")
}
else {
val amount = FluidContainerRegistry.getFluidForFilledItem(filled).amount
from.drain(amount, true)
inventory.decrStackSize(selectedSlot, 1)
InventoryUtils.insertIntoInventory(filled, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots))
if (filled.getCount > 0) {
InventoryUtils.spawnStackInWorld(position, filled)
}
result(true, amount)
}
}
else stack.getItem match {
case into: IFluidContainerItem =>
Option(FluidUtils.fluidHandlerOf(stack)) match {
case Some(handler) =>
val drained = from.drain(amount, false)
val transferred = into.fill(stack, drained, true)
val transferred = handler.fill(drained, true)
if (transferred > 0) {
from.drain(transferred, true)
result(true, transferred)
}
else result(Unit, "incompatible or no fluid")
case _ => result(Unit, "item is full or not a fluid container")
case _ => result(Unit, "item is not a fluid container")
}
case _ => result(Unit, "nothing selected")
}
@ -116,17 +79,11 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware
}
private def withFluidInfo(slot: Int, f: (Option[FluidStack], Int) => Array[AnyRef]) = {
def fluidInfo(stack: ItemStack) = {
if (FluidContainerRegistry.isFilledContainer(stack)) {
Option((Option(FluidContainerRegistry.getFluidForFilledItem(stack)), FluidContainerRegistry.getContainerCapacity(stack)))
}
else if (FluidContainerRegistry.isEmptyContainer(stack)) {
Option((None, FluidContainerRegistry.getContainerCapacity(stack)))
}
else stack.getItem match {
case from: IFluidContainerItem => Option((Option(from.getFluid(stack)), from.getCapacity(stack)))
case _ => None
}
def fluidInfo(stack: ItemStack) = Option(FluidUtils.fluidHandlerOf(stack)) match {
case Some(handler) if handler.getTankProperties.length > 0 =>
val props = handler.getTankProperties()(0)
Option((Option(props.getContents), props.getCapacity))
case _ => None
}
inventory.getStackInSlot(slot) match {

View File

@ -15,7 +15,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
fluidInTank(selectedTank) match {
case Some(stack) =>
FluidUtils.fluidHandlerAt(position.offset(side), side.getOpposite) match {
case Some(handler) => result(Option(handler.getTankInfo(side.getOpposite)).exists(_.exists(other => stack.isFluidEqual(other.fluid))))
case Some(handler) => result(Option(handler.getTankProperties).exists(_.exists(other => stack.isFluidEqual(other.getContents))))
case _ => result(false)
}
case _ => result(false)
@ -35,14 +35,14 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
case Some(handler) =>
tank.getFluid match {
case stack: FluidStack =>
val drained = handler.drain(facing.getOpposite, new FluidStack(stack, amount), true)
val drained = handler.drain(new FluidStack(stack, amount), true)
if ((drained != null && drained.amount > 0) || amount == 0) {
val filled = tank.fill(drained, true)
result(true, filled)
}
else result(Unit, "incompatible or no fluid")
case _ =>
val transferred = tank.fill(handler.drain(facing.getOpposite, amount, true), true)
val transferred = tank.fill(handler.drain(amount, true), true)
result(transferred > 0, transferred)
}
case _ => result(Unit, "incompatible or no fluid")
@ -65,7 +65,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
case Some(handler) =>
tank.getFluid match {
case stack: FluidStack =>
val filled = handler.fill(facing.getOpposite, new FluidStack(stack, amount), true)
val filled = handler.fill(new FluidStack(stack, amount), true)
if (filled > 0 || amount == 0) {
tank.drain(filled, true)
result(true, filled)

View File

@ -14,7 +14,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted {
FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite).map(info => Option(info.fluid).fold(0)(_.amount)).sum)
result(handler.getTankProperties.map(info => Option(info.getContents).fold(0)(_.amount)).sum)
case _ => result(Unit, "no tank")
}
}
@ -24,7 +24,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted {
val facing = checkSideForAction(args, 0)
FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite).map(_.capacity).foldLeft(0)((max, capacity) => math.max(max, capacity)))
result(handler.getTankProperties.map(_.getCapacity).foldLeft(0)((max, capacity) => math.max(max, capacity)))
case _ => result(Unit, "no tank")
}
}
@ -34,7 +34,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted {
val facing = checkSideForAction(args, 0)
FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite))
result(handler.getTankProperties)
case _ => result(Unit, "no tank")
}
}

View File

@ -7,6 +7,7 @@ import net.minecraft.block.BlockDynamicLiquid
import net.minecraft.block.BlockLiquid
import net.minecraft.block.BlockStaticLiquid
import net.minecraft.init.Blocks
import net.minecraft.item.ItemStack
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.EnumFacing
import net.minecraftforge.fluids.Fluid
@ -15,9 +16,11 @@ import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.FluidTank
import net.minecraftforge.fluids.FluidTankInfo
import net.minecraftforge.fluids.IFluidBlock
import net.minecraftforge.fluids.IFluidHandler
import net.minecraftforge.fluids.capability
import net.minecraftforge.fluids.capability.CapabilityFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fluids.capability.IFluidHandlerItem
import net.minecraftforge.fluids.capability.IFluidTankProperties
object FluidUtils {
/**
@ -38,6 +41,12 @@ object FluidUtils {
case _ => None
}
def fluidHandlerOf(stack: ItemStack): IFluidHandlerItem = Option(stack) match {
case Some(itemStack) if itemStack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null) =>
itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)
case _ => null
}
/**
* Transfers some fluid between two fluid handlers.
* <p/>
@ -47,10 +56,10 @@ object FluidUtils {
* <p/>
* This returns <tt>true</tt> if some fluid was transferred.
*/
def transferBetweenFluidHandlers(source: IFluidHandler, sourceSide: EnumFacing, sink: IFluidHandler, sinkSide: EnumFacing, limit: Int = Fluid.BUCKET_VOLUME) = {
val drained = source.drain(sourceSide, limit, false)
val filled = sink.fill(sinkSide, drained, false)
sink.fill(sinkSide, source.drain(sourceSide, filled, true), true)
def transferBetweenFluidHandlers(source: IFluidHandler, sink: IFluidHandler, limit: Int = Fluid.BUCKET_VOLUME) = {
val drained = source.drain(limit, false)
val filled = sink.fill(drained, false)
sink.fill(source.drain(filled, true), true)
}
/**
@ -63,7 +72,7 @@ object FluidUtils {
def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sinkPos: BlockPosition, sinkSide: EnumFacing, limit: Int = Fluid.BUCKET_VOLUME) =
fluidHandlerAt(sourcePos, sourceSide).fold(0)(source =>
fluidHandlerAt(sinkPos, sinkSide).fold(0)(sink =>
transferBetweenFluidHandlers(source, sourceSide, sink, sinkSide, limit)))
transferBetweenFluidHandlers(source, sink, limit)))
/**
* Lookup fluid taking into account flowing liquid blocks...
@ -77,17 +86,17 @@ object FluidUtils {
// ----------------------------------------------------------------------- //
private class GenericBlockWrapper(position: BlockPosition) extends IFluidHandler {
override def canDrain(from: EnumFacing, fluid: Fluid): Boolean = currentWrapper.fold(false)(_.canDrain(from, fluid))
override def canDrain(from: EnumFacing, fluid: Fluid): Boolean = currentWrapper.fold(false)(_.drain(new FluidStack(fluid, 1), false).amount > 0)
override def drain(from: EnumFacing, resource: FluidStack, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(from, resource, doDrain))
override def drain(from: EnumFacing, resource: FluidStack, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(resource, doDrain))
override def drain(from: EnumFacing, maxDrain: Int, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(from, maxDrain, doDrain))
override def drain(from: EnumFacing, maxDrain: Int, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(maxDrain, doDrain))
override def canFill(from: EnumFacing, fluid: Fluid): Boolean = currentWrapper.fold(false)(_.canFill(from, fluid))
override def canFill(from: EnumFacing, fluid: Fluid): Boolean = currentWrapper.fold(false)(_.fill(new FluidStack(fluid, 1), false) > 0)
override def fill(from: EnumFacing, resource: FluidStack, doFill: Boolean): Int = currentWrapper.fold(0)(_.fill(from, resource, doFill))
override def fill(from: EnumFacing, resource: FluidStack, doFill: Boolean): Int = currentWrapper.fold(0)(_.fill(resource, doFill))
override def getTankInfo(from: EnumFacing): Array[FluidTankInfo] = currentWrapper.fold(Array.empty[FluidTankInfo])(_.getTankInfo(from))
override def getTankInfo(from: EnumFacing): Array[IFluidTankProperties] = currentWrapper.fold(Array.empty[IFluidTankProperties])(_.getTankProperties)
def currentWrapper = if (position.world.get.blockExists(position)) position.world.get.getBlock(position) match {
case block: IFluidBlock => Option(new FluidBlockWrapper(position, block))

View File

@ -59,7 +59,7 @@ object ItemCosts {
terminate(Items.SLIME_BALL)
terminate(Items.STICK)
def hasCosts(stack: ItemStack) = !Mods.CraftingCosts.isAvailable && {
def hasCosts(stack: ItemStack) = {
val ingredients = computeIngredients(stack)
ingredients.nonEmpty && (ingredients.size > 1 || !ingredients.head._1.isItemEqual(stack))
}