From 371a32e88189e701c2cc777c952a69f6c0a4ad8f Mon Sep 17 00:00:00 2001 From: Vexatos Date: Mon, 25 Apr 2016 19:55:03 +0200 Subject: [PATCH 1/5] Added MFU. No Manual entry, no tooltip, no texture, not tested, recipe unfinished. --- src/main/resources/application.conf | 7 + .../assets/opencomputers/lang/en_US.lang | 4 + .../opencomputers/recipes/default.recipes | 5 + src/main/scala/li/cil/oc/Constants.scala | 1 + src/main/scala/li/cil/oc/Settings.scala | 2 + .../oc/common/event/BlockChangeHandler.scala | 71 +++++++ .../scala/li/cil/oc/common/init/Items.scala | 1 + .../li/cil/oc/common/item/UpgradeMF.scala | 38 ++++ .../opencomputers/DriverUpgradeMF.scala | 52 +++++ .../opencomputers/ModOpenComputers.scala | 3 + .../cil/oc/server/component/UpgradeMF.scala | 182 ++++++++++++++++++ 11 files changed, 366 insertions(+) create mode 100644 src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala create mode 100644 src/main/scala/li/cil/oc/common/item/UpgradeMF.scala create mode 100644 src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala create mode 100644 src/main/scala/li/cil/oc/server/component/UpgradeMF.scala diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index a662f9621..95ae454b0 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -807,6 +807,10 @@ opencomputers { # Energy consumed when reconfiguring nanomachines. nanomachinesReconfigure: 5000 + + # Energy consumed by a MFU per tick while connected. + # Similar to `wirelessCostPerRange`, this is multiplied with the distance to the bound block. + mfuRelay: 1 } # The rate at which different blocks accept external power. All of these @@ -1342,6 +1346,9 @@ opencomputers { # The maximum range between the drone/robot and a villager for a trade to # be performed by the trading upgrade tradingRange: 8.0 + + # Radius the MFU is able to operate in + mfuRange: 3 } # Settings for mod integration (the mod previously known as OpenComponents). diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 9fa64316e..2cb09e01e 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -144,6 +144,7 @@ item.oc.UpgradeHover1.name=Hover Upgrade (Tier 2) item.oc.UpgradeInventory.name=Inventory Upgrade item.oc.UpgradeInventoryController.name=Inventory Controller Upgrade item.oc.UpgradeLeash.name=Leash Upgrade +item.oc.UpgradeMF.name=MFU item.oc.UpgradeNavigation.name=Navigation Upgrade item.oc.UpgradePiston.name=Piston Upgrade item.oc.UpgradeSign.name=Sign I/O Upgrade @@ -370,6 +371,9 @@ oc:tooltip.UpgradeGenerator=Can be used to generate energy from fuel on the go. oc:tooltip.UpgradeHover=This upgrade allows robots to fly higher above the ground without having to climb walls.[nl] Maximum height: §f%s§7 oc:tooltip.UpgradeInventory=This upgrade provides inventory space to a robot or drone. Without one of these, they will not be able to store items internally. oc:tooltip.UpgradeInventoryController=This upgrade allows robots and drones more control in how it interacts with external inventories, and allows robots to swap their equipped tool with an item in their inventory. +oc:tooltip.UpgradeMF=TODO really, do this +oc:tooltip.UpgradeMF.Linked=§fConnection established§7 +oc:tooltip.UpgradeMF.Unlinked=§fNo connection§7 oc:tooltip.UpgradeLeash=Allows some devices, such as drones, to bind Isaa- excuse me... *chatter* My apologies. I'm just being told this is actually used to put animals on a leash. Multiple animals, even. Odd. oc:tooltip.UpgradeNavigation=Can be used to determine the position and orientation of a device. The position is relative to the center of the map that was used to craft this upgrade. oc:tooltip.UpgradePiston=This upgrade is very pushy. It allows moving blocks, similar to when using a piston. It does §lnot§7 move entities, however. diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index d006c6b61..f827717aa 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -295,6 +295,11 @@ inventoryControllerUpgrade { [dropper, "oc:circuitChip2", craftingPiston] [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] } +mfu { + input: [["oc:chamelium", gemLapis, "oc:chamelium"] + ["oc:linkedCard", "oc:adapter", "oc:linkedCard"] + ["oc:chamelium", gemLapis, "oc:chamelium"]] +} leashUpgrade { input: [[ingotIron, lead, ingotIron] [lead, "oc:materialCU", lead] diff --git a/src/main/scala/li/cil/oc/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index d43386194..0541ffb31 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -118,6 +118,7 @@ object Constants { final val LinkedCard = "linkedCard" final val LootDisk = "lootDisk" final val LuaBios = "luaBios" + final val MFU = "mfu" final val Manual = "manual" final val MicrocontrollerCaseCreative = "microcontrollerCaseCreative" final val MicrocontrollerCaseTier1 = "microcontrollerCase1" diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index 8eb7f165d..5e730c159 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -214,6 +214,7 @@ class Settings(val config: Config) { val transposerCost = config.getDouble("power.cost.transposer") max 0 val nanomachineCost = config.getDouble("power.cost.nanomachineInput") max 0 val nanomachineReconfigureCost = config.getDouble("power.cost.nanomachinesReconfigure") max 0 + val mfuCost = config.getDouble("power.cost.mfuRelay") max 0 // power.rate val accessPointRate = config.getDouble("power.rate.accessPoint") max 0 @@ -348,6 +349,7 @@ class Settings(val config: Config) { val serverRackSwitchTier = (config.getInt("misc.serverRackSwitchTier") - 1) max Tier.None min Tier.Three val redstoneDelay = config.getDouble("misc.redstoneDelay") max 0 val tradingRange = config.getDouble("misc.tradingRange") max 0 + val mfuRange = config.getInt("misc.mfuRange") max 0 min 128 // ----------------------------------------------------------------------- // // nanomachines diff --git a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala new file mode 100644 index 000000000..ec43a3af0 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala @@ -0,0 +1,71 @@ +package li.cil.oc.common.event + +import cpw.mods.fml.common.eventhandler.SubscribeEvent +import li.cil.oc.util.BlockPosition +import net.minecraft.entity.Entity +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.world.{IWorldAccess, World} +import net.minecraftforge.event.world.WorldEvent + +import scala.collection.mutable + +/** + * + * @author Vexatos + */ +object BlockChangeHandler { + + def addListener(listener: ChangeListener, coord: BlockPosition) = { + changeListeners.synchronized { + changeListeners.put(listener, coord) + } + } + + private val changeListeners = mutable.WeakHashMap.empty[ChangeListener, BlockPosition] + + @SubscribeEvent + def onWorldLoad(e: WorldEvent.Load) { + e.world.addWorldAccess(new Listener(e.world)) + } + + trait ChangeListener { + def onBlockChanged() + } + + private class Listener(world: World) extends IWorldAccess { + + override def markBlockForUpdate(x: Int, y: Int, z: Int): Unit = { + val current = BlockPosition(x, y, z, world) + changeListeners.synchronized { + for ((listener, coord) <- changeListeners) if (coord.equals(current)) { + listener.onBlockChanged() + } + } + } + + override def playRecord(recordName: String, x: Int, y: Int, z: Int) {} + + override def playAuxSFX(player: EntityPlayer, sfxType: Int, x: Int, y: Int, z: Int, data: Int) {} + + override def onEntityDestroy(entity: Entity) {} + + override def destroyBlockPartially(breakerId: Int, x: Int, y: Int, z: Int, progress: Int) {} + + override def markBlockForRenderUpdate(x: Int, y: Int, z: Int) {} + + override def spawnParticle(particleType: String, x: Double, y: Double, z: Double, velX: Double, velY: Double, velZ: Double) {} + + override def playSound(soundName: String, x: Double, y: Double, z: Double, volume: Float, pitch: Float) {} + + override def broadcastSound(soundID: Int, x: Int, y: Int, z: Int, data: Int) {} + + override def playSoundToNearExcept(player: EntityPlayer, soundName: String, x: Double, y: Double, z: Double, volume: Float, pitch: Float) {} + + override def markBlockRangeForRenderUpdate(x1: Int, y1: Int, z1: Int, x2: Int, y2: Int, z2: Int) {} + + override def onEntityCreate(entity: Entity) {} + + override def onStaticEntitiesChanged() {} + } + +} diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index 52c038f1b..5a95871ba 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -534,6 +534,7 @@ object Items extends ItemAPI { Recipes.addSubItem(new item.DiskDriveMountable(multi), Constants.ItemName.DiskDriveMountable, "oc:diskDriveMountable") Recipes.addSubItem(new item.UpgradeTrading(multi), Constants.ItemName.TradingUpgrade, "oc:tradingUpgrade") registerItem(new item.DiamondChip(multi), Constants.ItemName.DiamondChip) + Recipes.addSubItem(new item.UpgradeMF(multi), Constants.ItemName.MFU, "oc:mfu") // Register aliases. for ((k, v) <- aliases) { diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala new file mode 100644 index 000000000..7e6e054a0 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala @@ -0,0 +1,38 @@ +package li.cil.oc.common.item + +import java.util + +import li.cil.oc.Settings +import li.cil.oc.util.ExtendedWorld._ +import li.cil.oc.util.{BlockPosition, Tooltip} +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.tileentity.TileEntity + +class UpgradeMF(val parent: Delegator) extends traits.Delegate with traits.ItemTier { + + override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + if (!player.worldObj.isRemote && player.isSneaking) { + player.worldObj.getTileEntity(position) match { + case tile: TileEntity => + if (!stack.hasTagCompound) { + stack.setTagCompound(new NBTTagCompound()) + } + val data = stack.getTagCompound + data.setIntArray(Settings.namespace + "coord", Array(position.x, position.y, position.z, player.worldObj.provider.dimensionId, side)) + return true + case _ => + } + } + super.onItemUseFirst(stack, player, position, side, hitX, hitY, hitZ) + } + + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { + stack.getTagCompound match { + case data: NBTTagCompound => + tooltip.addAll(Tooltip.get(super.unlocalizedName + (if (data.hasKey("coord")) ".Linked" else ".Unlinked"))) + case _ => + } + } +} diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala new file mode 100644 index 000000000..945469e2b --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala @@ -0,0 +1,52 @@ +package li.cil.oc.integration.opencomputers + +import li.cil.oc.api.driver.EnvironmentProvider +import li.cil.oc.api.driver.item.HostAware +import li.cil.oc.api.network.{EnvironmentHost, ManagedEnvironment} +import li.cil.oc.common.{Slot, Tier} +import li.cil.oc.server.component +import li.cil.oc.util.BlockPosition +import li.cil.oc.{Constants, Settings, api} +import net.minecraft.item.ItemStack +import net.minecraftforge.common.DimensionManager +import net.minecraftforge.common.util.ForgeDirection + +/** + * + * @author Vexatos + */ +object DriverUpgradeMF extends Item with HostAware { + override def worksWith(stack: ItemStack): Boolean = isOneOf(stack, + api.Items.get(Constants.ItemName.MFU)) + + override def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]): Boolean = + worksWith(stack) && isAdapter(host) + + override def slot(stack: ItemStack): String = Slot.Upgrade + + override def tier(stack: ItemStack) = Tier.Three + + override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = { + if (host.world != null && !host.world.isRemote) { + if (stack.hasTagCompound) { + stack.getTagCompound.getIntArray(Settings.namespace + "coord") match { + case Array(x, y, z, dim, side) => + Option(DimensionManager.getWorld(dim)) match { + case Some(world) => return new component.UpgradeMF(host, BlockPosition(x, y, z), ForgeDirection.getOrientation(side)) + case _ => // Invalid dimension ID + } + case _ => // Invalid tag + } + } + } + null + } + + object Provider extends EnvironmentProvider { + override def getEnvironment(stack: ItemStack): Class[_] = + if (worksWith(stack)) + classOf[component.UpgradeMF] + else null + } + +} diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index d415189a9..cf009766e 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -79,6 +79,7 @@ object ModOpenComputers extends ModProxy { MinecraftForge.EVENT_BUS.register(Analyzer) MinecraftForge.EVENT_BUS.register(AngelUpgradeHandler) + MinecraftForge.EVENT_BUS.register(BlockChangeHandler) MinecraftForge.EVENT_BUS.register(ChunkloaderUpgradeHandler) MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(ExperienceUpgradeHandler) @@ -147,6 +148,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(DriverUpgradeTankController) api.Driver.add(DriverUpgradeTractorBeam) api.Driver.add(DriverUpgradeTrading) + api.Driver.add(DriverUpgradeMF) api.Driver.add(DriverAPU.Provider) api.Driver.add(DriverDataCard.Provider) @@ -174,6 +176,7 @@ object ModOpenComputers extends ModProxy { api.Driver.add(DriverUpgradeSign.Provider) api.Driver.add(DriverUpgradeTankController.Provider) api.Driver.add(DriverUpgradeTractorBeam.Provider) + api.Driver.add(DriverUpgradeMF.Provider) api.Driver.add(EnvironmentProviderBlocks) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala new file mode 100644 index 000000000..9b3a8c90b --- /dev/null +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -0,0 +1,182 @@ +package li.cil.oc.server.component + +import li.cil.oc.api.network._ +import li.cil.oc.api.{Network, prefab} +import li.cil.oc.common.event.BlockChangeHandler +import li.cil.oc.common.event.BlockChangeHandler.ChangeListener +import li.cil.oc.util.BlockPosition +import li.cil.oc.util.ExtendedWorld._ +import li.cil.oc.{Settings, api} +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.util.Vec3 +import net.minecraftforge.common.util.ForgeDirection + +/** + * Mostly stolen from li.cil.oc.common.tileentity.Adapter + * + * @author Sangar, Vexatos + */ +class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: ForgeDirection) extends prefab.ManagedEnvironment with ChangeListener { + override val node = Network.newNode(this, Visibility.None). + withConnector(). + create() + + private var otherEnv: Option[api.network.Environment] = None + private var otherDrv: Option[(ManagedEnvironment, api.driver.SidedBlock)] = None + private var blockData: Option[BlockData] = None + + override val canUpdate = true + + // Not checking for range yet because host may be a moving adapter, who knows? + BlockChangeHandler.addListener(this, coord) + + private def updateBoundState() { + if (node != null && node.network != null && coord.world.exists(_.provider.dimensionId == host.world.provider.dimensionId) + && coord.toVec3.distanceTo(Vec3.createVectorHelper(host.xPosition, host.yPosition, host.zPosition)) <= Settings.get.mfuRange) { + host.world.getTileEntity(coord) match { + case env: api.network.Environment => + otherEnv = Some(env) + // Remove any driver that might be there. + otherDrv match { + case Some((environment, driver)) => + node.disconnect(environment.node) + environment.save(blockData.get.data) + Option(environment.node).foreach(_.remove()) + otherDrv = None + case _ => // Nothing to do here. + } + node.connect(env.node) + case _ => + // Remove any environment that might have been there. + otherEnv match { + case Some(environment) => + node.disconnect(environment.node) + otherEnv = None + case _ => // Nothing to do here. + } + val (world, x, y, z) = (coord.world.get, coord.x, coord.y, coord.z) + Option(api.Driver.driverFor(world, coord.x, coord.y, coord.z, dir)) match { + case Some(newDriver) => + otherDrv match { + case Some((oldEnvironment, driver)) => + if (newDriver != driver) { + // This is... odd. Maybe moved by some other mod? First, clean up. + otherDrv = None + blockData = None + node.disconnect(oldEnvironment.node) + + // Then rebuild - if we have something. + val environment = newDriver.createEnvironment(world, x, y, z, dir) + if (environment != null) { + otherDrv = Some((environment, newDriver)) + blockData = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + node.connect(environment.node) + } + } // else: the more things change, the more they stay the same. + case _ => + // A challenger appears. Maybe. + val environment = newDriver.createEnvironment(world, x, y, z, dir) + if (environment != null) { + otherDrv = Some((environment, newDriver)) + blockData match { + case Some(data) if data.name == environment.getClass.getName => + environment.load(data.data) + case _ => + } + blockData = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + node.connect(environment.node) + } + } + case _ => otherDrv match { + case Some((environment, driver)) => + // We had something there, but it's gone now... + node.disconnect(environment.node) + environment.save(blockData.get.data) + Option(environment.node).foreach(_.remove()) + otherDrv = None + case _ => // Nothing before, nothing now. + } + } + } + } + } + + private def disconnect() { + otherEnv match { + case Some(environment) => + node.disconnect(environment.node) + otherEnv = None + case _ => // Nothing to do here. + } + otherDrv match { + case Some((environment, driver)) => + node.disconnect(environment.node) + environment.save(blockData.get.data) + Option(environment.node).foreach(_.remove()) + otherDrv = None + case _ => // Nothing to do here. + } + } + + override def onBlockChanged() = updateBoundState() + + override def update() { + super.update() + otherDrv match { + case Some((env, drv)) if env.canUpdate => env.update() + case _ => // No driver + } + if (host.world.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (!node.tryChangeBuffer(-Settings.get.mfuCost * Settings.get.tickFrequency + * coord.toVec3.distanceTo(Vec3.createVectorHelper(host.xPosition, host.yPosition, host.zPosition)))) { + disconnect() + } + } + } + + override def onConnect(node: Node) { + super.onConnect(node) + if (node == this.node) { + updateBoundState() + } + } + + override def onDisconnect(node: Node) { + super.onDisconnect(node) + otherEnv match { + case Some(env) if node == env.node => otherEnv = None + case _ => // No environment + } + otherDrv match { + case Some((env, drv)) if node == env.node => otherDrv = None + case _ => // No driver + } + } + + override def load(nbt: NBTTagCompound) { + super.load(nbt) + Option(nbt.getCompoundTag(Settings.namespace + "adapter.block")) match { + case Some(blockNbt: NBTTagCompound) => + if (blockNbt.hasKey("name") && blockNbt.hasKey("data")) { + blockData = Some(new BlockData(blockNbt.getString("name"), blockNbt.getCompoundTag("data"))) + } + case _ => // Invalid tag + } + } + + override def save(nbt: NBTTagCompound) { + super.save(nbt) + val blockNbt = new NBTTagCompound() + blockData.foreach({ data => + otherDrv.foreach(_._1.save(data.data)) + blockNbt.setString("name", data.name) + blockNbt.setTag("data", data.data) + }) + nbt.setTag(Settings.namespace + "adapter.block", blockNbt) + } + + // ----------------------------------------------------------------------- // + + private class BlockData(val name: String, val data: NBTTagCompound) + +} From ca2a8ae3712cdeda06fb8a783a4f766b6c2fc439 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Sat, 7 May 2016 15:09:04 +0200 Subject: [PATCH 2/5] Fixes to MFU. It actually works now. --- src/main/scala/li/cil/oc/Localization.scala | 2 ++ .../oc/common/event/BlockChangeHandler.scala | 6 ++++ .../li/cil/oc/common/item/UpgradeMF.scala | 29 +++++++------------ .../opencomputers/DriverUpgradeMF.scala | 2 +- .../cil/oc/server/component/UpgradeMF.scala | 3 ++ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main/scala/li/cil/oc/Localization.scala b/src/main/scala/li/cil/oc/Localization.scala index 433e66965..9d853a65c 100644 --- a/src/main/scala/li/cil/oc/Localization.scala +++ b/src/main/scala/li/cil/oc/Localization.scala @@ -170,6 +170,8 @@ object Localization { def PrintLightValue(level: Int) = localizeImmediately("tooltip.Print.LightValue", level.toString) def PrintRedstoneLevel(level: Int) = localizeImmediately("tooltip.Print.RedstoneLevel", level.toString) + + def MFULinked(isLinked: Boolean) = localizeImmediately(if (isLinked) "tooltip.UpgradeMF.Linked" else "tooltip.UpgradeMF.Unlinked") } } diff --git a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala index ec43a3af0..626deadb1 100644 --- a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala @@ -21,6 +21,12 @@ object BlockChangeHandler { } } + def removeListener(listener: ChangeListener) = { + changeListeners.synchronized { + changeListeners.remove(listener) + } + } + private val changeListeners = mutable.WeakHashMap.empty[ChangeListener, BlockPosition] @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala index 7e6e054a0..4f4b12687 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala @@ -2,37 +2,30 @@ package li.cil.oc.common.item import java.util -import li.cil.oc.Settings -import li.cil.oc.util.ExtendedWorld._ -import li.cil.oc.util.{BlockPosition, Tooltip} +import li.cil.oc.util.BlockPosition +import li.cil.oc.{Localization, Settings} import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound -import net.minecraft.tileentity.TileEntity class UpgradeMF(val parent: Delegator) extends traits.Delegate with traits.ItemTier { override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = { if (!player.worldObj.isRemote && player.isSneaking) { - player.worldObj.getTileEntity(position) match { - case tile: TileEntity => - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - val data = stack.getTagCompound - data.setIntArray(Settings.namespace + "coord", Array(position.x, position.y, position.z, player.worldObj.provider.dimensionId, side)) - return true - case _ => + if (!stack.hasTagCompound) { + stack.setTagCompound(new NBTTagCompound()) } + val data = stack.getTagCompound + data.setIntArray(Settings.namespace + "coord", Array(position.x, position.y, position.z, player.worldObj.provider.dimensionId, side)) + return true } super.onItemUseFirst(stack, player, position, side, hitX, hitY, hitZ) } override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { - stack.getTagCompound match { - case data: NBTTagCompound => - tooltip.addAll(Tooltip.get(super.unlocalizedName + (if (data.hasKey("coord")) ".Linked" else ".Unlinked"))) - case _ => - } + tooltip.add(Localization.Tooltip.MFULinked(stack.getTagCompound match { + case data: NBTTagCompound => data.hasKey(Settings.namespace +"coord") + case _ => false + })) } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala index 945469e2b..1c6c511c3 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala @@ -32,7 +32,7 @@ object DriverUpgradeMF extends Item with HostAware { stack.getTagCompound.getIntArray(Settings.namespace + "coord") match { case Array(x, y, z, dim, side) => Option(DimensionManager.getWorld(dim)) match { - case Some(world) => return new component.UpgradeMF(host, BlockPosition(x, y, z), ForgeDirection.getOrientation(side)) + case Some(world) => return new component.UpgradeMF(host, BlockPosition(x, y, z, world), ForgeDirection.getOrientation(side)) case _ => // Invalid dimension ID } case _ => // Invalid tag diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala index 9b3a8c90b..fb235d41d 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -151,6 +151,9 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo case Some((env, drv)) if node == env.node => otherDrv = None case _ => // No driver } + if(node == this.node) { + BlockChangeHandler.removeListener(this) + } } override def load(nbt: NBTTagCompound) { From 4c665723dc17aaa82f950a66bab80afbdc0d421e Mon Sep 17 00:00:00 2001 From: Vexatos Date: Sat, 7 May 2016 15:21:00 +0200 Subject: [PATCH 3/5] Made block change listener handling a little more safe. --- .../cil/oc/common/event/BlockChangeHandler.scala | 15 +++++---------- .../li/cil/oc/server/component/UpgradeMF.scala | 8 ++++---- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala index 626deadb1..6f6230bfd 100644 --- a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.event import cpw.mods.fml.common.eventhandler.SubscribeEvent +import li.cil.oc.common.EventHandler import li.cil.oc.util.BlockPosition import net.minecraft.entity.Entity import net.minecraft.entity.player.EntityPlayer @@ -16,15 +17,11 @@ import scala.collection.mutable object BlockChangeHandler { def addListener(listener: ChangeListener, coord: BlockPosition) = { - changeListeners.synchronized { - changeListeners.put(listener, coord) - } + EventHandler.scheduleServer(() => changeListeners.put(listener, coord)) } def removeListener(listener: ChangeListener) = { - changeListeners.synchronized { - changeListeners.remove(listener) - } + EventHandler.scheduleServer(() => changeListeners.remove(listener)) } private val changeListeners = mutable.WeakHashMap.empty[ChangeListener, BlockPosition] @@ -42,10 +39,8 @@ object BlockChangeHandler { override def markBlockForUpdate(x: Int, y: Int, z: Int): Unit = { val current = BlockPosition(x, y, z, world) - changeListeners.synchronized { - for ((listener, coord) <- changeListeners) if (coord.equals(current)) { - listener.onBlockChanged() - } + for ((listener, coord) <- changeListeners) if (coord.equals(current)) { + listener.onBlockChanged() } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala index fb235d41d..bde3d6764 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -27,9 +27,6 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo override val canUpdate = true - // Not checking for range yet because host may be a moving adapter, who knows? - BlockChangeHandler.addListener(this, coord) - private def updateBoundState() { if (node != null && node.network != null && coord.world.exists(_.provider.dimensionId == host.world.provider.dimensionId) && coord.toVec3.distanceTo(Vec3.createVectorHelper(host.xPosition, host.yPosition, host.zPosition)) <= Settings.get.mfuRange) { @@ -137,6 +134,9 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo override def onConnect(node: Node) { super.onConnect(node) if (node == this.node) { + // Not checking for range yet because host may be a moving adapter, who knows? + BlockChangeHandler.addListener(this, coord) + updateBoundState() } } @@ -151,7 +151,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo case Some((env, drv)) if node == env.node => otherDrv = None case _ => // No driver } - if(node == this.node) { + if (node == this.node) { BlockChangeHandler.removeListener(this) } } From 60f403131b80f449641c024c05f0254a656209b7 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Sat, 7 May 2016 22:53:16 +0200 Subject: [PATCH 4/5] Made MFU respect sided environments. --- .../cil/oc/server/component/UpgradeMF.scala | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala index bde3d6764..46498330b 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -1,13 +1,15 @@ package li.cil.oc.server.component import li.cil.oc.api.network._ -import li.cil.oc.api.{Network, prefab} +import li.cil.oc.api.prefab import li.cil.oc.common.event.BlockChangeHandler import li.cil.oc.common.event.BlockChangeHandler.ChangeListener +import li.cil.oc.server.network import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.{Settings, api} import net.minecraft.nbt.NBTTagCompound +import net.minecraft.tileentity.TileEntity import net.minecraft.util.Vec3 import net.minecraftforge.common.util.ForgeDirection @@ -17,7 +19,7 @@ import net.minecraftforge.common.util.ForgeDirection * @author Sangar, Vexatos */ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: ForgeDirection) extends prefab.ManagedEnvironment with ChangeListener { - override val node = Network.newNode(this, Visibility.None). + override val node = api.Network.newNode(this, Visibility.None). withConnector(). create() @@ -27,11 +29,24 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo override val canUpdate = true + private def otherNode(tile: TileEntity, f: (Node) => Unit) { + network.Network.getNetworkNode(tile, dir) match { + case Some(otherNode) => f(otherNode) + case _ => // Nothing to do here + } + } + private def updateBoundState() { if (node != null && node.network != null && coord.world.exists(_.provider.dimensionId == host.world.provider.dimensionId) && coord.toVec3.distanceTo(Vec3.createVectorHelper(host.xPosition, host.yPosition, host.zPosition)) <= Settings.get.mfuRange) { host.world.getTileEntity(coord) match { - case env: api.network.Environment => + case env: TileEntity with api.network.Environment => + otherEnv match { + case Some(environment: TileEntity) => + otherNode(environment, node.disconnect) + otherEnv = None + case _ => // Nothing to do here. + } otherEnv = Some(env) // Remove any driver that might be there. otherDrv match { @@ -42,12 +57,12 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo otherDrv = None case _ => // Nothing to do here. } - node.connect(env.node) + otherNode(env, node.connect) case _ => // Remove any environment that might have been there. otherEnv match { - case Some(environment) => - node.disconnect(environment.node) + case Some(environment: TileEntity) => + otherNode(environment, node.disconnect) otherEnv = None case _ => // Nothing to do here. } @@ -100,8 +115,8 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo private def disconnect() { otherEnv match { - case Some(environment) => - node.disconnect(environment.node) + case Some(environment: TileEntity) => + otherNode(environment, node.disconnect) otherEnv = None case _ => // Nothing to do here. } @@ -144,7 +159,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo override def onDisconnect(node: Node) { super.onDisconnect(node) otherEnv match { - case Some(env) if node == env.node => otherEnv = None + case Some(env: TileEntity) => otherNode(env, (otherNode) => if (node == otherNode) otherEnv = None) case _ => // No environment } otherDrv match { From 4c3b7d03d8bc4ed1d07daade108514d27719e446 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Fri, 3 Feb 2017 22:06:36 +0100 Subject: [PATCH 5/5] Added device info to MFU. --- src/main/resources/application.conf | 2 +- src/main/scala/li/cil/oc/Constants.scala | 1 + .../oc/common/event/BlockChangeHandler.scala | 1 - .../cil/oc/server/component/UpgradeMF.scala | 22 +++++++++++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index e4a3d3510..9c834010e 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -809,7 +809,7 @@ opencomputers { nanomachinesReconfigure: 5000 # Energy consumed by a MFU per tick while connected. - # Similar to `wirelessCostPerRange`, this is multiplied with the distance to the bound block. + # Similarly to `wirelessCostPerRange`, this is multiplied with the distance to the bound block. mfuRelay: 1 } diff --git a/src/main/scala/li/cil/oc/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index bcaa4ce63..3eee3ce77 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -175,6 +175,7 @@ object Constants { object DeviceInfo { final val DefaultVendor = "MightyPirates GmbH & Co. KG" + final val Scummtech = "Scummtech, Inc." } diff --git a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala index 6f6230bfd..3830de1e7 100644 --- a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala @@ -11,7 +11,6 @@ import net.minecraftforge.event.world.WorldEvent import scala.collection.mutable /** - * * @author Vexatos */ object BlockChangeHandler { diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala index 46498330b..a5870c618 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -1,5 +1,11 @@ package li.cil.oc.server.component +import java.util + +import li.cil.oc.Constants +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.network._ import li.cil.oc.api.prefab import li.cil.oc.common.event.BlockChangeHandler @@ -7,18 +13,21 @@ import li.cil.oc.common.event.BlockChangeHandler.ChangeListener import li.cil.oc.server.network import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import li.cil.oc.{Settings, api} +import li.cil.oc.Settings +import li.cil.oc.api import net.minecraft.nbt.NBTTagCompound import net.minecraft.tileentity.TileEntity import net.minecraft.util.Vec3 import net.minecraftforge.common.util.ForgeDirection +import scala.collection.convert.WrapAsJava._ + /** * Mostly stolen from li.cil.oc.common.tileentity.Adapter * * @author Sangar, Vexatos */ -class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: ForgeDirection) extends prefab.ManagedEnvironment with ChangeListener { +class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: ForgeDirection) extends prefab.ManagedEnvironment with ChangeListener with DeviceInfo { override val node = api.Network.newNode(this, Visibility.None). withConnector(). create() @@ -29,6 +38,15 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Fo override val canUpdate = true + private final lazy val deviceInfo = Map( + DeviceAttribute.Class -> DeviceClass.Bus, + DeviceAttribute.Description -> "Remote Adapter", + DeviceAttribute.Vendor -> Constants.DeviceInfo.Scummtech, + DeviceAttribute.Product -> "ERR NAME NOT FOUND" + ) + + override def getDeviceInfo: util.Map[String, String] = deviceInfo + private def otherNode(tile: TileEntity, f: (Node) => Unit) { network.Network.getNetworkNode(tile, dir) match { case Some(otherNode) => f(otherNode)