| package li.cil.oc.common.template |
| |
| import li.cil.oc.Constants |
| import li.cil.oc.Localization |
| import li.cil.oc.Settings |
| import li.cil.oc.api |
| import li.cil.oc.api.driver._ |
| import li.cil.oc.api.driver.item.Container |
| import li.cil.oc.api.driver.item.Inventory |
| import li.cil.oc.api.driver.item.Memory |
| import li.cil.oc.api.driver.item.Processor |
| import li.cil.oc.common.Slot |
| import li.cil.oc.common.Tier |
| import net.minecraft.inventory.IInventory |
| import net.minecraft.item.ItemStack |
| import net.minecraft.util.IChatComponent |
| |
| import scala.collection.mutable |
| |
| abstract class Template { |
| protected val suggestedComponents = Array( |
| "BIOS" -> hasComponent(Constants.ItemName.EEPROM) _, |
| "Screen" -> hasComponent(Constants.BlockName.ScreenTier1) _, |
| "Keyboard" -> hasComponent(Constants.BlockName.Keyboard) _, |
| "GraphicsCard" -> ((inventory: IInventory) => Array(Constants.ItemName.GraphicsCardTier1, Constants.ItemName.GraphicsCardTier2, Constants.ItemName.GraphicsCardTier3).exists(name => hasComponent(name)(inventory))), |
| "Inventory" -> hasInventory _, |
| "OS" -> hasFileSystem _) |
| |
| protected def hostClass: Class[_ <: EnvironmentHost] |
| |
| protected def validateComputer(inventory: IInventory): Array[AnyRef] = { |
| val hasCase = caseTier(inventory) != Tier.None |
| val hasCPU = this.hasCPU(inventory) |
| val hasRAM = this.hasRAM(inventory) |
| val complexity = this.complexity(inventory) |
| val maxComplexity = this.maxComplexity(inventory) |
| |
| val valid = hasCase && hasCPU && hasRAM && complexity <= maxComplexity |
| |
| val progress = |
| if (!hasCPU) Localization.Assembler.InsertCPU |
| else if (!hasRAM) Localization.Assembler.InsertRAM |
| else Localization.Assembler.Complexity(complexity, maxComplexity) |
| |
| val warnings = mutable.ArrayBuffer.empty[IChatComponent] |
| for ((name, check) <- suggestedComponents) { |
| if (!check(inventory)) { |
| warnings += Localization.Assembler.Warning(name) |
| } |
| } |
| if (warnings.length > 0) { |
| warnings.prepend(Localization.Assembler.Warnings) |
| } |
| |
| Array(valid: java.lang.Boolean, progress, warnings.toArray) |
| } |
| |
| protected def exists(inventory: IInventory, p: ItemStack => Boolean) = { |
| (0 until inventory.getSizeInventory).exists(slot => Option(inventory.getStackInSlot(slot)) match { |
| case Some(stack) => p(stack) |
| case _ => false |
| }) |
| } |
| |
| protected def hasCPU(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { |
| case _: Processor => true |
| case _ => false |
| }) |
| |
| protected def hasRAM(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { |
| case _: Memory => true |
| case _ => false |
| }) |
| |
| protected def hasComponent(name: String)(inventory: IInventory) = exists(inventory, stack => Option(api.Items.get(stack)) match { |
| case Some(descriptor) => descriptor.name == name |
| case _ => false |
| }) |
| |
| protected def hasInventory(inventory: IInventory) = exists(inventory, api.Driver.driverFor(_, hostClass) match { |
| case _: Inventory => true |
| case _ => false |
| }) |
| |
| protected def hasFileSystem(inventory: IInventory) = exists(inventory, stack => Option(api.Driver.driverFor(stack, hostClass)) match { |
| case Some(driver) => driver.slot(stack) == Slot.Floppy || driver.slot(stack) == Slot.HDD |
| case _ => false |
| }) |
| |
| protected def complexity(inventory: IInventory) = { |
| var acc = 0 |
| for (slot <- 1 until inventory.getSizeInventory) { |
| val stack = inventory.getStackInSlot(slot) |
| acc += (Option(api.Driver.driverFor(stack, hostClass)) match { |
| case Some(driver: Processor) => 0 // CPUs are exempt, since they control the limit. |
| case Some(driver: Container) => (1 + driver.tier(stack)) * 2 |
| case Some(driver) if driver.slot(stack) != Slot.EEPROM => 1 + driver.tier(stack) |
| case _ => 0 |
| }) |
| } |
| acc |
| } |
| |
| protected def maxComplexity(inventory: IInventory) = { |
| val caseTier = this.caseTier(inventory) |
| val cpuTier = (0 until inventory.getSizeInventory).foldRight(0)((slot, acc) => { |
| val stack = inventory.getStackInSlot(slot) |
| acc + (api.Driver.driverFor(stack, hostClass) match { |
| case processor: Processor => processor.tier(stack) |
| case _ => 0 |
| }) |
| }) |
| if (caseTier >= Tier.One && cpuTier >= Tier.One) { |
| Settings.deviceComplexityByTier(caseTier) - (math.min(2, caseTier) - cpuTier) * 6 |
| } |
| else 0 |
| } |
| |
| protected def caseTier(inventory: IInventory): Int |
| } |