Conflicts:
	src/main/java/li/cil/oc/server/TickHandler.scala
	src/main/resources/mcmod.info
	src/main/scala/li/cil/oc/common/Proxy.scala
	src/main/scala/li/cil/oc/common/block/Cable.scala
	src/main/scala/li/cil/oc/common/block/Capacitor.scala
	src/main/scala/li/cil/oc/common/block/Delegate.scala
	src/main/scala/li/cil/oc/common/block/Delegator.scala
	src/main/scala/li/cil/oc/common/block/DiskDrive.scala
	src/main/scala/li/cil/oc/common/block/KeyboardDeprecated.scala
	src/main/scala/li/cil/oc/common/block/RobotProxy.scala
	src/main/scala/li/cil/oc/common/block/Router.scala
	src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala
	src/main/scala/li/cil/oc/server/PacketHandler.scala
	src/main/scala/li/cil/oc/server/network/Network.scala
This commit is contained in:
Florian Nücke 2014-03-02 22:35:06 +01:00
commit 340752f491
22 changed files with 369 additions and 64 deletions

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,79 @@
package li.cil.oc.common.multipart
/* TODO FMP
import codechicken.lib.vec.{Vector3, Cuboid6}
import codechicken.multipart._
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.network
import li.cil.oc.api.network.{Message, Node, Visibility}
import li.cil.oc.client.renderer.tileentity.CableRenderer
import li.cil.oc.common.block.Cable
import li.cil.oc.server.TickHandler
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{Blocks, Settings, api}
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.AxisAlignedBB
import org.lwjgl.opengl.GL11
import scala.collection.convert.WrapAsJava
import scala.collection.convert.WrapAsScala._
class CablePart(val original: Option[Node] = None) extends DelegatePart with TCuboidPart with TNormalOcclusion with network.Environment {
val node = api.Network.newNode(this, Visibility.None).create()
override def delegate = Blocks.cable
def getType = "oc:cable"
override def doesTick = false
override def getBounds = new Cuboid6(Cable.bounds(world, x, y, z))
override def getOcclusionBoxes = WrapAsJava.asJavaIterable(Iterable(new Cuboid6(AxisAlignedBB.getBoundingBox(-0.125 + 0.5, -0.125 + 0.5, -0.125 + 0.5, 0.125 + 0.5, 0.125 + 0.5, 0.125 + 0.5))))
override def getRenderBounds = new Cuboid6(Cable.bounds(world, x, y, z).offset(x, y, z))
override def invalidateConvertedTile() {
super.invalidateConvertedTile()
original.foreach(_.neighbors.foreach(_.connect(this.node)))
}
override def onPartChanged(part: TMultiPart) {
super.onPartChanged(part)
api.Network.joinOrCreateNetwork(tile)
}
override def onWorldJoin() {
super.onWorldJoin()
TickHandler.schedule(this)
}
override def onWorldSeparate() {
super.onWorldSeparate()
Option(node).foreach(_.remove)
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
node.load(nbt.getCompoundTag(Settings.namespace + "node"))
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setNewCompoundTag(Settings.namespace + "node", node.save)
}
@SideOnly(Side.CLIENT)
override def renderDynamic(pos: Vector3, frame: Float, pass: Int) {
super.renderDynamic(pos, frame, pass)
GL11.glTranslated(pos.x, pos.y, pos.z)
CableRenderer.renderCable(Cable.neighbors(world, x, y, z))
GL11.glTranslated(-pos.x, -pos.y, -pos.z)
}
override def onMessage(message: Message) {}
override def onDisconnect(node: Node) {}
override def onConnect(node: Node) {}
}
*/

View File

@ -0,0 +1,24 @@
package li.cil.oc.common.multipart
/* TODO FMP
import codechicken.multipart.{TIconHitEffects, TMultiPart}
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.common.block.Delegate
import net.minecraft.entity.Entity
import net.minecraft.util.MovingObjectPosition
import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava
abstract class DelegatePart extends TMultiPart with TIconHitEffects {
def delegate: Delegate
override def pickItem(hit: MovingObjectPosition) = delegate.createItemStack()
override def getDrops = WrapAsJava.asJavaIterable(Iterable(delegate.createItemStack()))
override def explosionResistance(entity: Entity) = delegate.explosionResistance(entity)
@SideOnly(Side.CLIENT)
override def getBrokenIcon(side: Int) = delegate.icon(ForgeDirection.getOrientation(side)).orNull
}
*/

View File

@ -0,0 +1,94 @@
package li.cil.oc.common.multipart
/* TODO FMP
import codechicken.lib.packet.PacketCustom
import codechicken.lib.raytracer.RayTracer
import codechicken.lib.vec.{Vector3, BlockCoord}
import codechicken.multipart.TileMultipart
import li.cil.oc.Blocks
import li.cil.oc.client.PacketSender
import li.cil.oc.common.block.Delegator
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.network.packet.Packet15Place
import net.minecraft.util.MovingObjectPosition
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.ForgeSubscribe
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
import net.minecraftforge.event.entity.player.{PlayerDestroyItemEvent, PlayerInteractEvent}
object EventHandler {
@ForgeSubscribe
def playerInteract(event: PlayerInteractEvent) {
val player = event.entityPlayer
if (event.action == Action.RIGHT_CLICK_BLOCK && player.getEntityWorld.isRemote) {
if (place(player)) {
event.setCanceled(true)
}
}
}
def place(player: EntityPlayer) = {
val world = player.getEntityWorld
val hit = RayTracer.reTrace(world, player)
if (hit != null) Delegator.subBlock(player.getHeldItem) match {
case Some(subBlock) if subBlock == Blocks.cable => placeDelegatePart(player, hit, new CablePart())
case _ => false
}
else false
}
protected def placeDelegatePart(player: EntityPlayer, hit: MovingObjectPosition, part: DelegatePart): Boolean = {
val world = player.getEntityWorld
if (world.isRemote && !player.isSneaking) {
// Attempt to use block activated like normal and tell the server the right stuff
val f = new Vector3(hit.hitVec).add(-hit.blockX, -hit.blockY, -hit.blockZ)
val block = Block.blocksList(world.getBlockId(hit.blockX, hit.blockY, hit.blockZ))
if (block != null && block.onBlockActivated(world, hit.blockX, hit.blockY, hit.blockZ, player, hit.sideHit, f.x.toFloat, f.y.toFloat, f.z.toFloat)) {
player.swingItem()
PacketCustom.sendToServer(new Packet15Place(
hit.blockX, hit.blockY, hit.blockZ, hit.sideHit,
player.inventory.getCurrentItem,
f.x.toFloat, f.y.toFloat, f.z.toFloat))
return false
}
}
val pos = new BlockCoord(hit.blockX, hit.blockY, hit.blockZ)
val posOutside = pos.copy().offset(hit.sideHit)
val inside = Option(TileMultipart.getOrConvertTile(world, pos))
val outside = Option(TileMultipart.getOrConvertTile(world, posOutside))
inside match {
case Some(t) if t.canAddPart(part) => placeMultiPart(player, part, pos)
case _ => outside match {
case Some(t) if t.canAddPart(part) => placeMultiPart(player, part, posOutside)
case _ => false
}
}
}
protected def placeMultiPart(player: EntityPlayer, part: DelegatePart, pos: BlockCoord) = {
val world = player.getEntityWorld
if (world.isRemote) {
player.swingItem()
PacketSender.sendMultiPlace()
}
else {
TileMultipart.addPart(world, pos, part)
world.playSoundEffect(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5,
part.delegate.parent.stepSound.getPlaceSound,
(part.delegate.parent.stepSound.getVolume + 1.0F) / 2.0F,
part.delegate.parent.stepSound.getPitch * 0.8F)
if (!player.capabilities.isCreativeMode) {
val held = player.getHeldItem
held.stackSize -= 1
if (held.stackSize == 0) {
player.inventory.mainInventory(player.inventory.currentItem) = null
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, held))
}
}
}
true
}
}
*/

View File

@ -0,0 +1,36 @@
package li.cil.oc.common.multipart
/* TODO FMP
import codechicken.lib.vec.BlockCoord
import codechicken.multipart.MultiPartRegistry.{IPartConverter, IPartFactory}
import codechicken.multipart.{TMultiPart, MultiPartRegistry}
import li.cil.oc.Blocks
import li.cil.oc.common.tileentity.Cable
import net.minecraft.world.World
import net.minecraftforge.common.MinecraftForge
object MultiPart extends IPartFactory with IPartConverter {
def init() {
MultiPartRegistry.registerConverter(this)
MultiPartRegistry.registerParts(this, Array("oc:cable"))
MinecraftForge.EVENT_BUS.register(EventHandler)
}
override def createPart(name: String, client: Boolean): TMultiPart = {
if (name.equals("oc:cable"))
return new CablePart()
null
}
override def canConvert(blockID: Int): Boolean = {
blockID == Blocks.cable.parent.blockID
}
override def convert(world: World, pos: BlockCoord) = {
world.getBlockTileEntity(pos.x, pos.y, pos.z) match {
case cable: Cable => new CablePart(Some(cable.node))
case _ => null
}
}
}
*/

View File

@ -12,6 +12,7 @@
"dependencies": [
"BuildCraft|Energy",
"ComputerCraft",
"ForgeMultipart",
"IC2",
"MineFactoryReloaded",
"ProjRed|Transmission",

View File

@ -108,6 +108,11 @@ object PacketSender {
pb.sendToServer()
}
def sendMultiPlace() {
val pb = new PacketBuilder(PacketType.MultiPartPlace)
pb.sendToServer()
}
def sendRobotStateRequest(dimension: Int, x: Int, y: Int, z: Int) {
val pb = new PacketBuilder(PacketType.RobotStateRequest)

View File

@ -4,11 +4,12 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent
import cpw.mods.fml.common.gameevent.PlayerEvent._
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
import cpw.mods.fml.common.{Loader, FMLCommonHandler}
import li.cil.oc.api.Network
import li.cil.oc.server.driver.Registry
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.LuaStateFactory
import li.cil.oc.util.mods.ProjectRed
import li.cil.oc.{UpdateCheck, api, Items, Settings}
import li.cil.oc.{UpdateCheck, Items, Settings}
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.{ItemMap, ItemStack}
import net.minecraft.server.MinecraftServer
@ -20,9 +21,16 @@ object EventHandler {
val pendingAdds = mutable.Buffer.empty[() => Unit]
def schedule(tileEntity: TileEntity) = pendingAdds.synchronized {
pendingAdds += (() => if (!tileEntity.isInvalid) api.Network.joinOrCreateNetwork(tileEntity))
pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity))
}
/* TODO FMP
@Optional.Method(modid = "ForgeMultipart")
def schedule(part: TMultiPart) = pendingAdds.synchronized {
pendingAdds += (() => Network.joinOrCreateNetwork(part.tile))
}
*/
@SubscribeEvent
def onTick(e: ServerTickEvent) = pendingAdds.synchronized {
for (callback <- pendingAdds) {

View File

@ -38,6 +38,7 @@ object PacketType extends Enumeration {
Clipboard,
MouseClickOrDrag,
MouseScroll,
MultiPartPlace,
RobotStateRequest,
ServerSide,
ServerRange = Value

View File

@ -17,6 +17,11 @@ class Proxy {
Blocks.init()
Items.init()
/* TODO FMP
if (Loader.isModLoaded("ForgeMultipart")) {
MultiPart.init()
}
*/
api.Driver.instance = driver.Registry
api.FileSystem.instance = fs.FileSystem

View File

@ -1,18 +1,21 @@
package li.cil.oc.common.block
import cpw.mods.fml.common.Loader
import cpw.mods.fml.relauncher.{SideOnly, Side}
import java.util
import li.cil.oc.api.network.{SidedEnvironment, Environment}
import li.cil.oc.common.tileentity
import li.cil.oc.Settings
import li.cil.oc.util.Tooltip
import li.cil.oc.{Settings, api}
import net.minecraft.block.Block
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.util.{IIcon, AxisAlignedBB}
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.IIcon
import net.minecraft.world.{IBlockAccess, World}
import net.minecraftforge.common.util.ForgeDirection
import net.minecraft.block.Block
class Cable(val parent: SpecialDelegator) extends SpecialDelegate {
val unlocalizedName = "Cable"
@ -40,12 +43,6 @@ class Cable(val parent: SpecialDelegator) extends SpecialDelegate {
override def createTileEntity(world: World) = Some(new tileentity.Cable)
override def update(world: World, x: Int, y: Int, z: Int) =
world.getTileEntity(x, y, z) match {
case cable: tileentity.Cable => api.Network.joinOrCreateNetwork(cable)
case _ =>
}
// ----------------------------------------------------------------------- //
override def isNormalCube(world: IBlockAccess, x: Int, y: Int, z: Int) = false
@ -91,21 +88,48 @@ object Cable {
def neighbors(world: IBlockAccess, x: Int, y: Int, z: Int) = {
var result = 0
val tileEntity = world.getTileEntity(x, y, z)
for (side <- ForgeDirection.VALID_DIRECTIONS) {
val (tx, ty, tz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
if (!world.isAirBlock(tx, ty, tz)) world.getTileEntity(tx, ty, tz) match {
case robot: tileentity.RobotProxy =>
case host: SidedEnvironment =>
val connects = if (host.getWorldObj.isRemote) host.canConnect(side.getOpposite) else host.sidedNode(side.getOpposite) != null
if (connects) {
result |= side.flag
}
case host: Environment => result |= side.flag
case _ =>
if (!world.isAirBlock(tx, ty, tz)) {
val neighborTileEntity = world.getTileEntity(tx, ty, tz)
val neighborHasNode = hasNetworkNode(neighborTileEntity, side.getOpposite)
val canConnect = !Loader.isModLoaded("ForgeMultipart") ||
(canConnectFromSide(tileEntity, side) && canConnectFromSide(neighborTileEntity, side.getOpposite))
if (neighborHasNode && canConnect) {
result |= side.flag
}
}
}
result
}
def bounds(world: IBlockAccess, x: Int, y: Int, z: Int) = Cable.cachedBounds(Cable.neighbors(world, x, y, z)).copy()
private def hasNetworkNode(tileEntity: TileEntity, side: ForgeDirection) =
tileEntity match {
case robot: tileentity.RobotProxy => false
case host: SidedEnvironment =>
if (host.getWorldObj.isRemote) host.canConnect(side)
else host.sidedNode(side) != null
case host: Environment => true
case host if Loader.isModLoaded("ForgeMultipart") => hasMultiPartNode(tileEntity)
case _ => false
}
private def hasMultiPartNode(tileEntity: TileEntity) =
tileEntity match {
/* TODO FMP
case host: TileMultipart => host.partList.exists(_.isInstanceOf[CablePart])
*/
case _ => false
}
private def canConnectFromSide(tileEntity: TileEntity, side: ForgeDirection) =
tileEntity match {
/* TODO FMP
case host: TileMultipart => !host.isSolid(side.ordinal)
*/
case _ => true
}
}

View File

@ -2,15 +2,15 @@ package li.cil.oc.common.block
import java.util
import li.cil.oc.common.tileentity
import li.cil.oc.Settings
import li.cil.oc.util.Tooltip
import li.cil.oc.{api, Settings}
import net.minecraft.block.Block
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.util.IIcon
import net.minecraft.world.{World, IBlockAccess}
import net.minecraftforge.common.util.ForgeDirection
import net.minecraft.block.Block
class Capacitor(val parent: SimpleDelegator) extends SimpleDelegate {
val unlocalizedName = "Capacitor"
@ -45,14 +45,6 @@ class Capacitor(val parent: SimpleDelegator) extends SimpleDelegate {
// ----------------------------------------------------------------------- //
override def update(world: World, x: Int, y: Int, z: Int) =
world.getTileEntity(x, y, z) match {
case capacitor: tileentity.Capacitor =>
api.Network.joinOrCreateNetwork(capacitor)
capacitor.recomputeCapacity(updateSecondGradeNeighbors = true)
case _ =>
}
override def neighborBlockChanged(world: World, x: Int, y: Int, z: Int, block: Block) =
world.getTileEntity(x, y, z) match {
case capacitor: tileentity.Capacitor => capacitor.recomputeCapacity()

View File

@ -36,6 +36,8 @@ trait Delegate {
def drops(world: World, x: Int, y: Int, z: Int, fortune: Int): Option[java.util.ArrayList[ItemStack]] = None
def explosionResistance(entity: Entity): Float = parent.getExplosionResistance(entity)
def isNormalCube(world: IBlockAccess, x: Int, y: Int, z: Int) = true
def validRotations(world: World, x: Int, y: Int, z: Int) = validRotations_

View File

@ -134,6 +134,12 @@ class Delegator[Child <: Delegate] extends Block(Material.iron) {
dropBlockAsItem(world, x, y, z, stack)
}
override def getExplosionResistance(entity: Entity, world: World, x: Int, y: Int, z: Int, explosionX: Double, explosionY: Double, explosionZ: Double) =
subBlock(world, x, y, z) match {
case Some(subBlock) => subBlock.explosionResistance(entity)
case _ => super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ)
}
override def isNormalCube(world: IBlockAccess, x: Int, y: Int, z: Int) =
subBlock(world.getBlockMetadata(x, y, z)) match {
case Some(subBlock) => subBlock.isNormalCube(world, x, y, z)

View File

@ -4,7 +4,7 @@ import cpw.mods.fml.common.Loader
import java.util
import li.cil.oc.common.{GuiType, tileentity}
import li.cil.oc.util.Tooltip
import li.cil.oc.{api, OpenComputers, Settings}
import li.cil.oc.{OpenComputers, Settings}
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
@ -44,12 +44,6 @@ class DiskDrive(val parent: SimpleDelegator) extends SimpleDelegate {
override def createTileEntity(world: World) = Some(new tileentity.DiskDrive)
override def update(world: World, x: Int, y: Int, z: Int) =
world.getTileEntity(x, y, z) match {
case drive: tileentity.DiskDrive => api.Network.joinOrCreateNetwork(drive)
case _ =>
}
// ----------------------------------------------------------------------- //
override def rightClick(world: World, x: Int, y: Int, z: Int, player: EntityPlayer,

View File

@ -1,9 +1,9 @@
package li.cil.oc.common.block
import java.util
import li.cil.oc.{Blocks, api, Settings}
import li.cil.oc.common.tileentity
import li.cil.oc.util.Tooltip
import li.cil.oc.{Blocks, Settings}
import net.minecraft.block.Block
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
@ -39,12 +39,6 @@ class KeyboardDeprecated(val parent: SpecialDelegator) extends SpecialDelegate {
override def createTileEntity(world: World) = Some(new tileentity.Keyboard(world.isRemote))
override def update(world: World, x: Int, y: Int, z: Int) =
world.getTileEntity(x, y, z) match {
case keyboard: tileentity.Keyboard => api.Network.joinOrCreateNetwork(keyboard)
case _ =>
}
// DEPRECATED Seems this isn't available anymore with stack info, use real
// items in 1.7 when needed since IDs are no problem anymore.
def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) =

View File

@ -8,7 +8,7 @@ import li.cil.oc.server.component.robot
import li.cil.oc.util.Tooltip
import li.cil.oc.{Blocks, Settings, OpenComputers}
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.{Entity, EntityLivingBase}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.{EnumRarity, ItemStack}
import net.minecraft.util.{IIcon, MovingObjectPosition, AxisAlignedBB, Vec3}
@ -71,6 +71,8 @@ class RobotProxy(val parent: SpecialDelegator) extends RedstoneAware with Specia
// ----------------------------------------------------------------------- //
override def explosionResistance(entity: Entity) = 10f
override def isNormalCube(world: IBlockAccess, x: Int, y: Int, z: Int) = false
override def isSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = false

View File

@ -2,7 +2,6 @@ package li.cil.oc.common.block
import java.util
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.common.tileentity
import li.cil.oc.util.Tooltip
import net.minecraft.client.renderer.texture.IIconRegister
@ -40,10 +39,4 @@ class Router(val parent: SimpleDelegator) extends SimpleDelegate {
override def hasTileEntity = true
override def createTileEntity(world: World) = Some(new tileentity.Router)
override def update(world: World, x: Int, y: Int, z: Int) =
world.getTileEntity(x, y, z) match {
case router: tileentity.Router => api.Network.joinOrCreateNetwork(router)
case _ =>
}
}

View File

@ -1,6 +1,6 @@
package li.cil.oc.common.tileentity
import li.cil.oc.api.network.Visibility
import li.cil.oc.api.network.{Node, Visibility}
import li.cil.oc.common.EventHandler
import li.cil.oc.{Settings, api}
import net.minecraftforge.common.util.ForgeDirection
@ -46,6 +46,13 @@ class Capacitor extends Environment with PassiveNode {
}
}
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
recomputeCapacity(updateSecondGradeNeighbors = true)
}
}
def recomputeCapacity(updateSecondGradeNeighbors: Boolean = false) {
node.setLocalBufferSize(
Settings.get.bufferCapacitor +

View File

@ -29,6 +29,7 @@ object PacketHandler extends CommonPacketHandler {
case PacketType.Clipboard => onClipboard(p)
case PacketType.MouseClickOrDrag => onMouseClick(p)
case PacketType.MouseScroll => onMouseScroll(p)
case PacketType.MultiPartPlace => onMultiPartPlace(p)
case PacketType.RobotStateRequest => onRobotStateRequest(p)
case PacketType.ServerRange => onServerRange(p)
case PacketType.ServerSide => onServerSide(p)
@ -142,6 +143,16 @@ object PacketHandler extends CommonPacketHandler {
}
}
def onMultiPartPlace(p: PacketParser) {
p.player match {
/* TODO FMP
case player: EntityPlayerMP => EventHandler.place(player)
*/
case _ => // Invalid packet.
}
}
def onRobotStateRequest(p: PacketParser) =
p.readTileEntity[RobotProxy]() match {
case Some(proxy) => proxy.world.markBlockForUpdate(proxy.x, proxy.y, proxy.z)

View File

@ -1,6 +1,6 @@
package li.cil.oc.server.network
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.{Loader, FMLCommonHandler}
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import cpw.mods.fml.relauncher.Side
import li.cil.oc.api.network.{Node => ImmutableNode, SidedEnvironment, Environment, Visibility}
@ -380,22 +380,29 @@ object Network extends api.detail.NetworkAPI {
}
override def joinOrCreateNetwork(tileEntity: TileEntity): Unit =
if (!tileEntity.getWorldObj.isRemote) {
if (!tileEntity.isInvalid && !tileEntity.getWorldObj.isRemote) {
for (side <- ForgeDirection.VALID_DIRECTIONS) {
getNetworkNode(tileEntity, side) match {
val (nx, ny, nz) = (
tileEntity.xCoord + side.offsetX,
tileEntity.yCoord + side.offsetY,
tileEntity.zCoord + side.offsetZ)
val localNode = getNetworkNode(tileEntity, side)
val neighborTileEntity = tileEntity.getWorldObj.getTileEntity(nx, ny, nz)
val neighborNode = getNetworkNode(neighborTileEntity, side.getOpposite)
localNode match {
case Some(node: MutableNode) =>
val (nx, ny, nz) = (
tileEntity.xCoord + side.offsetX,
tileEntity.yCoord + side.offsetY,
tileEntity.zCoord + side.offsetZ)
getNetworkNode(tileEntity.getWorldObj.getTileEntity(nx, ny, nz), side.getOpposite) match {
case Some(neighbor: MutableNode) if neighbor != node && neighbor.network != null => neighbor.connect(node)
case _ => // Ignore.
neighborNode match {
case Some(neighbor: MutableNode) if neighbor != node && neighbor.network != null =>
val canConnect = !Loader.isModLoaded("ForgeMultipart") ||
(canConnectFromSide(tileEntity, side) && canConnectFromSide(neighborTileEntity, side.getOpposite))
if (canConnect) neighbor.connect(node)
else node.disconnect(neighbor)
case _ =>
}
if (node.network == null) {
joinNewNetwork(node)
}
case _ => // No node for this side or bad environment.
case _ =>
}
}
}
@ -410,9 +417,29 @@ object Network extends api.detail.NetworkAPI {
tileEntity match {
case host: SidedEnvironment => Option(host.sidedNode(side))
case host: Environment => Some(host.node)
case host if Loader.isModLoaded("ForgeMultipart") => getMultiPartNode(host)
case _ => None
}
private def getMultiPartNode(tileEntity: TileEntity) =
tileEntity match {
/* TODO FMP
case host: TileMultipart => host.partList.find(_.isInstanceOf[CablePart]) match {
case Some(part: CablePart) => Some(part.node)
case _ => None
}
*/
case _ => None
}
private def canConnectFromSide(tileEntity: TileEntity, side: ForgeDirection) =
tileEntity match {
/* TODO FMP
case host: TileMultipart => !host.isSolid(side.ordinal)
*/
case _ => true
}
// ----------------------------------------------------------------------- //
def newNode(host: Environment, reachability: Visibility) = new NodeBuilder(host, reachability)