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
if (panel == null) return
zLevel += 350
val itemsPerPage = ReflectionHelper.getPrivateValue(classOf[ItemPanel], LayoutManager.itemPanel, "itemsPerPage").asInstanceOf[Int]
val itemsPerPage = panel.getGrid.getPerPage
for (index <- 0 until itemsPerPage) {
val rect = panel.getSlotRect(index)
val rect = panel.getGrid.getSlotRect(index)
val slot = panel.getSlotMouseOver(rect.x, rect.y)
if (slot != null) hoveredSlot match {
case Some(hovered) =>

View File

@ -4,12 +4,14 @@ import java.lang
import appeng.api.AEApi
import appeng.api.config.Actionable
import appeng.api.networking.crafting.ICraftingLink
import appeng.api.networking.crafting.ICraftingRequester
import appeng.api.networking.IGridNode
import appeng.api.networking.crafting.{CraftingItemList, ICraftingLink, ICraftingRequester}
import appeng.api.networking.security.{BaseActionSource, IActionHost, MachineSource}
import appeng.api.networking.storage.IBaseMonitor
import appeng.api.storage.IMEMonitorHandlerReceiver
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.util.item.AEItemStack
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.ExtendedNBT._
import li.cil.oc.util.ResultWrapper._
import net.minecraft.item.Item
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.DimensionManager
@ -42,6 +43,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.language.existentials
//noinspection ScalaUnusedSymbol
// 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] {
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.")
def getCpus(context: Context, args: Arguments): Array[AnyRef] = {
val buffer = new mutable.ListBuffer[Map[String, Any]]
var index = 0
tile.getProxy.getCrafting.getCpus.foreach(cpu => {
buffer.append(Map(
"name" -> cpu.getName,
"storage" -> cpu.getAvailableStorage,
"coprocessors" -> cpu.getCoProcessors,
"busy" -> cpu.isBusy))
"busy" -> cpu.isBusy,
"cpu" -> new Cpu(tile, index, cpu.asInstanceOf[CraftingCPUCluster])
))
index += 1
})
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 = {
if (stack == null) return false
filter.forall {
case (key: String, value: AnyRef) => {
case (key: String, value: AnyRef) =>
val stack_value = stack.get(key)
value match {
case number: Number => stack_value match {
@ -153,10 +159,10 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
}
}
}
}
object NetworkControl {
//noinspection ScalaUnusedSymbol
class Craftable(var controller: TileEntity with IGridProxyable with IActionHost, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester {
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) {
links -= link
}
// rv1
def injectCratedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable) = stack
override def injectCraftedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable): IAEItemStack = stack
// rv2
def injectCraftedItems(link: ICraftingLink, stack: IAEItemStack, p3: Actionable) = stack
override def getActionableNode: IGridNode = controller.getActionableNode
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) = controller.getGridNode(side)
override def getGridNode(side: ForgeDirection): IGridNode = controller.getGridNode(side)
// ----------------------------------------------------------------------- //
@ -204,9 +207,9 @@ object NetworkControl {
val future = craftingGrid.beginCraftingJob(controller.getWorldObj, controller.getProxy.getGrid, source, request, null)
val prioritizePower = args.optBoolean(1, true)
val cpuName = args.optString(2, "")
val cpu = if (!cpuName.isEmpty()) {
val cpu = if (!cpuName.isEmpty) {
controller.getProxy.getCrafting.getCpus.collectFirst({
case c if cpuName.equals(c.getName()) => c
case c if cpuName.equals(c.getName) => c
}).orNull
} else null
@ -240,19 +243,7 @@ object NetworkControl {
override def load(nbt: NBTTagCompound) {
super.load(nbt)
stack = AEItemStack.loadItemStackFromNBT(nbt)
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]) {
controller = tileEntity.asInstanceOf[TileEntity with IGridProxyable with IActionHost]
}
})
}
loadController(nbt, c => controller = c)
links ++= nbt.getTagList("links", NBT.TAG_COMPOUND).map(
(nbt: NBTTagCompound) => AEApi.instance.storage.loadCraftingLink(nbt, this))
}
@ -260,16 +251,83 @@ object NetworkControl {
override def save(nbt: NBTTagCompound) {
super.save(nbt)
stack.writeToNBT(nbt)
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)
}
saveController(controller, nbt)
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 {
private var isComputing = true
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)
if (controller != null)
controller.getProxy.getStorage.getItemInventory.addListener(this, null)
var items : IItemList[IAEItemStack] = null
var i : java.util.Iterator[IAEItemStack] = null
var index = 0
private var addedListener = true
private var items : IItemList[IAEItemStack] = null
private var itemIterator : java.util.Iterator[IAEItemStack] = null
private var index = 0
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) {
items = controller.getProxy.getStorage.getItemInventory.getStorageList
if (items != null)
i = items.iterator
if (i != null)
itemIterator = items.iterator
if (itemIterator != null)
for (_ <- 1 to index) {
if (i.hasNext)
i.next
if (itemIterator.hasNext)
itemIterator.next
}
}
if (this.i == null && this.items != null)
this.i = items.iterator
if (!this.i.hasNext()) return null
if (this.itemIterator == null && this.items != null)
this.itemIterator = items.iterator
if (!this.itemIterator.hasNext)
return null
index += 1
Array[AnyRef](convert(i.next(), controller))
Array[AnyRef](convert(itemIterator.next(), controller))
}
override def load(nbt: NBTTagCompound) {
super.load(nbt)
if (nbt.hasKey("dimension")) {
val dimension = nbt.getInteger("dimension")
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)
}
})
}
addedListener = false
loadController(nbt, c => controller = c)
}
override def save(nbt: NBTTagCompound) {
super.save(nbt)
nbt.setInteger("index", index)
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)
saveController(controller, nbt)
}
}
var valid = true
def dispose(context: Nothing): Unit = {
private var valid = true
override def dispose(context: Context): Unit = {
valid = false
}
override def isValid(verificationToken: Any): Boolean = valid
override def onListUpdate(): Unit = {
this.items = null
}
@ -386,6 +439,7 @@ object NetworkControl {
this.items = null
}
}
def aeCraftItem(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): IAEItemStack = {
val patterns = tile.getProxy.getCrafting.getCraftingFor(aeItem, null, 0, tile.getWorldObj)
patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match {
@ -400,6 +454,7 @@ object NetworkControl {
else
aeCraftItem(aeItem, tile)
}
def convert(aeItem: IAEItemStack, tile: TileEntity with IGridProxyable): java.util.HashMap[String, AnyRef] = {
def hashConvert(value: java.util.HashMap[_, _]) = {
val hash = new java.util.HashMap[String, AnyRef]
@ -419,4 +474,29 @@ object NetworkControl {
}
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)
}
}
}