Extended AE crafting CPU API

Fixed NEI valid items highlight after API update
Some AE integration code cleanup
This commit is contained in:
repo_alt 2022-01-07 03:58:03 +03:00
parent b30c1bf743
commit 872dc5b888
2 changed files with 155 additions and 75 deletions

View File

@ -180,9 +180,9 @@ abstract class DynamicGuiContainer[C <: Container](container: C) extends CustomG
val panel = LayoutManager.itemPanel val panel = LayoutManager.itemPanel
if (panel == null) return if (panel == null) return
zLevel += 350 zLevel += 350
val itemsPerPage = ReflectionHelper.getPrivateValue(classOf[ItemPanel], LayoutManager.itemPanel, "itemsPerPage").asInstanceOf[Int] val itemsPerPage = panel.getGrid.getPerPage
for (index <- 0 until itemsPerPage) { for (index <- 0 until itemsPerPage) {
val rect = panel.getSlotRect(index) val rect = panel.getGrid.getSlotRect(index)
val slot = panel.getSlotMouseOver(rect.x, rect.y) val slot = panel.getSlotMouseOver(rect.x, rect.y)
if (slot != null) hoveredSlot match { if (slot != null) hoveredSlot match {
case Some(hovered) => case Some(hovered) =>

View File

@ -4,12 +4,14 @@ import java.lang
import appeng.api.AEApi import appeng.api.AEApi
import appeng.api.config.Actionable import appeng.api.config.Actionable
import appeng.api.networking.crafting.ICraftingLink import appeng.api.networking.IGridNode
import appeng.api.networking.crafting.ICraftingRequester import appeng.api.networking.crafting.{CraftingItemList, ICraftingLink, ICraftingRequester}
import appeng.api.networking.security.{BaseActionSource, IActionHost, MachineSource} import appeng.api.networking.security.{BaseActionSource, IActionHost, MachineSource}
import appeng.api.networking.storage.IBaseMonitor import appeng.api.networking.storage.IBaseMonitor
import appeng.api.storage.IMEMonitorHandlerReceiver import appeng.api.storage.IMEMonitorHandlerReceiver
import appeng.api.storage.data.{IAEItemStack, IItemList} import appeng.api.storage.data.{IAEItemStack, IItemList}
import appeng.api.util.AECableType
import appeng.me.cluster.implementations.CraftingCPUCluster
import appeng.me.helpers.IGridProxyable import appeng.me.helpers.IGridProxyable
import appeng.util.item.AEItemStack import appeng.util.item.AEItemStack
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
@ -28,7 +30,6 @@ import li.cil.oc.util.DatabaseAccess
import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedArguments._
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ResultWrapper._ import li.cil.oc.util.ResultWrapper._
import net.minecraft.item.Item
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.DimensionManager import net.minecraftforge.common.DimensionManager
@ -42,6 +43,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future import scala.concurrent.Future
import scala.language.existentials import scala.language.existentials
//noinspection ScalaUnusedSymbol
// Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it. // Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it.
trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] { trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] {
def tile: AETile def tile: AETile
@ -54,12 +56,16 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
@Callback(doc = "function():table -- Get a list of tables representing the available CPUs in the network.") @Callback(doc = "function():table -- Get a list of tables representing the available CPUs in the network.")
def getCpus(context: Context, args: Arguments): Array[AnyRef] = { def getCpus(context: Context, args: Arguments): Array[AnyRef] = {
val buffer = new mutable.ListBuffer[Map[String, Any]] val buffer = new mutable.ListBuffer[Map[String, Any]]
var index = 0
tile.getProxy.getCrafting.getCpus.foreach(cpu => { tile.getProxy.getCrafting.getCpus.foreach(cpu => {
buffer.append(Map( buffer.append(Map(
"name" -> cpu.getName, "name" -> cpu.getName,
"storage" -> cpu.getAvailableStorage, "storage" -> cpu.getAvailableStorage,
"coprocessors" -> cpu.getCoProcessors, "coprocessors" -> cpu.getCoProcessors,
"busy" -> cpu.isBusy)) "busy" -> cpu.isBusy,
"cpu" -> new Cpu(tile, index, cpu.asInstanceOf[CraftingCPUCluster])
))
index += 1
}) })
result(buffer.toArray) result(buffer.toArray)
} }
@ -141,7 +147,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
private def matches(stack: java.util.HashMap[String, AnyRef], filter: scala.collection.mutable.Map[String, AnyRef]): Boolean = { private def matches(stack: java.util.HashMap[String, AnyRef], filter: scala.collection.mutable.Map[String, AnyRef]): Boolean = {
if (stack == null) return false if (stack == null) return false
filter.forall { filter.forall {
case (key: String, value: AnyRef) => { case (key: String, value: AnyRef) =>
val stack_value = stack.get(key) val stack_value = stack.get(key)
value match { value match {
case number: Number => stack_value match { case number: Number => stack_value match {
@ -150,13 +156,13 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
} }
case any => any.toString.equals(stack_value.toString) case any => any.toString.equals(stack_value.toString)
} }
}
} }
} }
} }
object NetworkControl { object NetworkControl {
//noinspection ScalaUnusedSymbol
class Craftable(var controller: TileEntity with IGridProxyable with IActionHost, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester { class Craftable(var controller: TileEntity with IGridProxyable with IActionHost, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester {
def this() = this(null, null) def this() = this(null, null)
@ -164,25 +170,22 @@ object NetworkControl {
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def getRequestedJobs = ImmutableSet.copyOf(links.toIterable) //noinspection RedundantCollectionConversion
override def getRequestedJobs: ImmutableSet[ICraftingLink] = ImmutableSet.copyOf(links.toIterable)
override def jobStateChange(link: ICraftingLink) { override def jobStateChange(link: ICraftingLink) {
links -= link links -= link
} }
// rv1 override def injectCraftedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable): IAEItemStack = stack
def injectCratedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable) = stack
// rv2 override def getActionableNode: IGridNode = controller.getActionableNode
def injectCraftedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable) = stack
override def getActionableNode = controller.getActionableNode override def getCableConnectionType(side: ForgeDirection): AECableType = controller.getCableConnectionType(side)
override def getCableConnectionType(side: ForgeDirection) = controller.getCableConnectionType(side) override def securityBreak(): Unit = controller.securityBreak()
override def securityBreak() = controller.securityBreak() override def getGridNode(side: ForgeDirection): IGridNode = controller.getGridNode(side)
override def getGridNode(side: ForgeDirection) = controller.getGridNode(side)
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -204,9 +207,9 @@ object NetworkControl {
val future = craftingGrid.beginCraftingJob(controller.getWorldObj, controller.getProxy.getGrid, source, request, null) val future = craftingGrid.beginCraftingJob(controller.getWorldObj, controller.getProxy.getGrid, source, request, null)
val prioritizePower = args.optBoolean(1, true) val prioritizePower = args.optBoolean(1, true)
val cpuName = args.optString(2, "") val cpuName = args.optString(2, "")
val cpu = if (!cpuName.isEmpty()) { val cpu = if (!cpuName.isEmpty) {
controller.getProxy.getCrafting.getCpus.collectFirst({ controller.getProxy.getCrafting.getCpus.collectFirst({
case c if cpuName.equals(c.getName()) => c case c if cpuName.equals(c.getName) => c
}).orNull }).orNull
} else null } else null
@ -240,19 +243,7 @@ object NetworkControl {
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
super.load(nbt) super.load(nbt)
stack = AEItemStack.loadItemStackFromNBT(nbt) stack = AEItemStack.loadItemStackFromNBT(nbt)
if (nbt.hasKey("dimension")) { loadController(nbt, c => controller = c)
val dimension = nbt.getInteger("dimension")
val x = nbt.getInteger("x")
val y = nbt.getInteger("y")
val z = nbt.getInteger("z")
EventHandler.scheduleServer(() => {
val world = DimensionManager.getWorld(dimension)
val tileEntity = world.getTileEntity(x, y, z)
if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IGridProxyable with IActionHost]) {
controller = tileEntity.asInstanceOf[TileEntity with IGridProxyable with IActionHost]
}
})
}
links ++= nbt.getTagList("links", NBT.TAG_COMPOUND).map( links ++= nbt.getTagList("links", NBT.TAG_COMPOUND).map(
(nbt: NBTTagCompound) => AEApi.instance.storage.loadCraftingLink(nbt, this)) (nbt: NBTTagCompound) => AEApi.instance.storage.loadCraftingLink(nbt, this))
} }
@ -260,16 +251,83 @@ object NetworkControl {
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {
super.save(nbt) super.save(nbt)
stack.writeToNBT(nbt) stack.writeToNBT(nbt)
if (controller != null && !controller.isInvalid) { saveController(controller, nbt)
nbt.setInteger("dimension", controller.getWorldObj.provider.dimensionId)
nbt.setInteger("x", controller.xCoord)
nbt.setInteger("y", controller.yCoord)
nbt.setInteger("z", controller.zCoord)
}
nbt.setNewTagList("links", links.map(_.writeToNBT _)) nbt.setNewTagList("links", links.map(_.writeToNBT _))
} }
} }
//noinspection ScalaUnusedSymbol
class Cpu(var controller: TileEntity with IGridProxyable, var index : Int, var cpu : CraftingCPUCluster) extends AbstractValue {
def this() = this(null, 0, null)
@Callback(doc = "function():boolean -- Cancel this CPU current crafting job.")
def cancel(context: Context, args: Arguments): Array[AnyRef] = {
if (!getCpu.isBusy)
result(false)
else {
getCpu.cancel()
result(true)
}
}
@Callback(doc = "function():boolean -- Is cpu active?")
def isActive(context: Context, args: Arguments): Array[AnyRef] = {
result(getCpu.isActive)
}
@Callback(doc = "function():boolean -- Is cpu busy?")
def isBusy(context: Context, args: Arguments): Array[AnyRef] = {
result(getCpu.isBusy)
}
@Callback(doc = "function():table -- Get currently crafted items.")
def activeItems(context: Context, args: Arguments): Array[AnyRef] = {
val list = AEApi.instance.storage.createItemList
getCpu.getListOfItem(list, CraftingItemList.ACTIVE)
result(list.map(item => convert(item, controller)).toArray)
}
@Callback(doc = "function():table -- Get pending items.")
def pendingItems(context: Context, args: Arguments): Array[AnyRef] = {
val list = AEApi.instance.storage.createItemList
getCpu.getListOfItem(list, CraftingItemList.PENDING)
result(list.map(item => convert(item, controller)).toArray)
}
@Callback(doc = "function():table -- Get stored items.")
def storedItems(context: Context, args: Arguments): Array[AnyRef] = {
val list = AEApi.instance.storage.createItemList
getCpu.getListOfItem(list, CraftingItemList.STORAGE)
result(list.map(item => convert(item, controller)).toArray)
}
private def getCpu = {
if (cpu == null && controller != null) {
var i = 0
for (c <- controller.getProxy.getCrafting.getCpus) {
if (i == index) {
cpu = c.asInstanceOf[CraftingCPUCluster]
}
i += 1
}
}
if (cpu == null)
throw new Exception("Broken CPU cluster")
cpu
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setInteger("index", index)
saveController(controller, nbt)
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
index = nbt.getInteger("index")
loadController(nbt, c => controller = c)
}
}
//noinspection ScalaUnusedSymbol
class CraftingStatus extends AbstractValue { class CraftingStatus extends AbstractValue {
private var isComputing = true private var isComputing = true
private var link: Option[ICraftingLink] = None private var link: Option[ICraftingLink] = None
@ -318,67 +376,62 @@ object NetworkControl {
} }
} }
class NetworkContents(var controller: TileEntity with IGridProxyable) extends AbstractValue with IMEMonitorHandlerReceiver[IAEItemStack] //noinspection ConvertNullInitializerToUnderscore
class NetworkContents(var controller: TileEntity with IGridProxyable with IActionHost) extends AbstractValue with IMEMonitorHandlerReceiver[IAEItemStack]
{ {
def this() = this(null) def this() = this(null)
if (controller != null) if (controller != null)
controller.getProxy.getStorage.getItemInventory.addListener(this, null) controller.getProxy.getStorage.getItemInventory.addListener(this, null)
var items : IItemList[IAEItemStack] = null private var addedListener = true
var i : java.util.Iterator[IAEItemStack] = null private var items : IItemList[IAEItemStack] = null
var index = 0 private var itemIterator : java.util.Iterator[IAEItemStack] = null
private var index = 0
override def call(context: Context, arguments: Arguments): Array[AnyRef] = { override def call(context: Context, arguments: Arguments): Array[AnyRef] = {
if (controller == null) return null if (controller == null)
return null
if (!addedListener) {
controller.getProxy.getStorage.getItemInventory.addListener(this, null)
addedListener = true
}
if (items == null) { if (items == null) {
items = controller.getProxy.getStorage.getItemInventory.getStorageList items = controller.getProxy.getStorage.getItemInventory.getStorageList
if (items != null) if (items != null)
i = items.iterator itemIterator = items.iterator
if (i != null) if (itemIterator != null)
for (_ <- 1 to index) { for (_ <- 1 to index) {
if (i.hasNext) if (itemIterator.hasNext)
i.next itemIterator.next
} }
} }
if (this.i == null && this.items != null) if (this.itemIterator == null && this.items != null)
this.i = items.iterator this.itemIterator = items.iterator
if (!this.i.hasNext()) return null if (!this.itemIterator.hasNext)
return null
index += 1 index += 1
Array[AnyRef](convert(i.next(), controller)) Array[AnyRef](convert(itemIterator.next(), controller))
} }
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
super.load(nbt) super.load(nbt)
if (nbt.hasKey("dimension")) { addedListener = false
val dimension = nbt.getInteger("dimension") loadController(nbt, c => controller = c)
val x = nbt.getInteger("x")
val y = nbt.getInteger("y")
val z = nbt.getInteger("z")
index = nbt.getInteger("index")
EventHandler.scheduleServer(() => {
val tileEntity = DimensionManager.getWorld(dimension).getTileEntity(x, y, z)
if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IGridProxyable]) {
controller = tileEntity.asInstanceOf[TileEntity with IGridProxyable]
if (controller!= null)
controller.getProxy.getStorage.getItemInventory.addListener(this, null)
}
})
}
} }
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {
super.save(nbt) super.save(nbt)
nbt.setInteger("index", index) nbt.setInteger("index", index)
if (controller != null && !controller.isInvalid) { saveController(controller, nbt)
nbt.setInteger("dimension", controller.getWorldObj.provider.dimensionId)
nbt.setInteger("x", controller.xCoord)
nbt.setInteger("y", controller.yCoord)
nbt.setInteger("z", controller.zCoord)
}
} }
var valid = true
def dispose(context: Nothing): Unit = { private var valid = true
override def dispose(context: Context): Unit = {
valid = false valid = false
} }
override def isValid(verificationToken: Any): Boolean = valid override def isValid(verificationToken: Any): Boolean = valid
override def onListUpdate(): Unit = { override def onListUpdate(): Unit = {
this.items = null this.items = null
} }
@ -386,6 +439,7 @@ object NetworkControl {
this.items = null this.items = null
} }
} }
def aeCraftItem(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): IAEItemStack = { def aeCraftItem(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): IAEItemStack = {
val patterns = tile.getProxy.getCrafting.getCraftingFor(aeItem, null, 0, tile.getWorldObj) val patterns = tile.getProxy.getCrafting.getCraftingFor(aeItem, null, 0, tile.getWorldObj)
patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match { patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match {
@ -400,6 +454,7 @@ object NetworkControl {
else else
aeCraftItem(aeItem, tile) aeCraftItem(aeItem, tile)
} }
def convert(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): java.util.HashMap[String, AnyRef] = { def convert(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): java.util.HashMap[String, AnyRef] = {
def hashConvert(value: java.util.HashMap[_, _]) = { def hashConvert(value: java.util.HashMap[_, _]) = {
val hash = new java.util.HashMap[String, AnyRef] val hash = new java.util.HashMap[String, AnyRef]
@ -419,4 +474,29 @@ object NetworkControl {
} }
null null
} }
private def loadController(nbt: NBTTagCompound, f : TileEntity with IGridProxyable with IActionHost => Unit ) : Unit = {
if (nbt.hasKey("dimension")) {
val dimension = nbt.getInteger("dimension")
val x = nbt.getInteger("x")
val y = nbt.getInteger("y")
val z = nbt.getInteger("z")
EventHandler.scheduleServer(() => {
val world = DimensionManager.getWorld(dimension)
val tileEntity = world.getTileEntity(x, y, z)
if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IGridProxyable with IActionHost]) {
f(tileEntity.asInstanceOf[TileEntity with IGridProxyable with IActionHost])
}
})
}
}
private def saveController(controller: TileEntity, nbt: NBTTagCompound): Unit = {
if (controller != null && !controller.isInvalid) {
nbt.setInteger("dimension", controller.getWorldObj.provider.dimensionId)
nbt.setInteger("x", controller.xCoord)
nbt.setInteger("y", controller.yCoord)
nbt.setInteger("z", controller.zCoord)
}
}
} }