mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 11:48:02 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
Conflicts: src/main/scala/li/cil/oc/common/item/Analyzer.scala src/main/scala/li/cil/oc/common/item/Debugger.scala src/main/scala/li/cil/oc/server/component/Agent.scala src/main/scala/li/cil/oc/server/component/DebugCard.scala src/main/scala/li/cil/oc/server/component/Transposer.scala src/main/scala/li/cil/oc/util/InventoryUtils.scala
This commit is contained in:
commit
c427dcc195
@ -465,8 +465,8 @@ opencomputers {
|
||||
# screens. This also controls how frequent distributors revalidate their
|
||||
# global state and secondary distributors, as well as how often the power
|
||||
# converter queries sources for energy (for now: only BuildCraft). If set
|
||||
# to 1, this would query every tick. The default queries every 20 ticks,
|
||||
# or in other words once per second.
|
||||
# to 1, this would query every tick. The default queries every 10 ticks,
|
||||
# or in other words twice per second.
|
||||
# Higher values mean more responsive power consumption, but slightly more
|
||||
# work per tick (shouldn't be that noticeable, though). Note that this
|
||||
# has no influence on the actual amount of energy required by computers
|
||||
|
@ -118,6 +118,7 @@ object EventHandler {
|
||||
@SubscribeEvent
|
||||
def playerLoggedIn(e: PlayerLoggedInEvent) {
|
||||
if (SideTracker.isServer) e.player match {
|
||||
case _: FakePlayer => // Nope
|
||||
case player: EntityPlayerMP =>
|
||||
if (!LuaStateFactory.isAvailable) {
|
||||
player.addChatMessage(Localization.Chat.WarningLuaFallback)
|
||||
|
@ -15,6 +15,7 @@ import net.minecraft.inventory.Slot
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTBase
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.FakePlayer
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
@ -155,6 +156,7 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory:
|
||||
val nbt = new NBTTagCompound()
|
||||
detectCustomDataChanges(nbt)
|
||||
for (entry <- crafters) entry match {
|
||||
case _: FakePlayer => // Nope
|
||||
case player: EntityPlayerMP => ServerPacketSender.sendContainerUpdate(this, nbt, player)
|
||||
case _ =>
|
||||
}
|
||||
|
@ -465,7 +465,13 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
|
||||
|
||||
override def interactFirst(player: EntityPlayer) = {
|
||||
if (player.isSneaking) {
|
||||
kill()
|
||||
if (api.Items.get(player.getCurrentEquippedItem) == api.Items.get(Constants.ItemName.Wrench)) {
|
||||
kill()
|
||||
}
|
||||
else if (!world.isRemote && !machine.isRunning) {
|
||||
preparePowerUp()
|
||||
start()
|
||||
}
|
||||
}
|
||||
else if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Drone.id, world, getEntityId, 0, 0)
|
||||
|
@ -16,6 +16,7 @@ import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.FakePlayer
|
||||
import net.minecraftforge.event.entity.player.EntityInteractEvent
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
|
||||
@ -59,6 +60,7 @@ object Analyzer {
|
||||
|
||||
private def analyzeNodes(nodes: Array[Node], player: EntityPlayer) = if (nodes != null) for (node <- nodes if node != null) {
|
||||
player match {
|
||||
case _: FakePlayer => // Nope
|
||||
case playerMP: EntityPlayerMP =>
|
||||
if (node != null) node.host match {
|
||||
case machine: Machine =>
|
||||
|
@ -9,11 +9,13 @@ import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.common.util.FakePlayer
|
||||
|
||||
class Debugger(val parent: Delegator) extends traits.Delegate {
|
||||
override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
val world = position.world.get
|
||||
player match {
|
||||
case _: FakePlayer => false // Nope
|
||||
case realPlayer: EntityPlayerMP =>
|
||||
world.getTileEntity(position) match {
|
||||
case host: SidedEnvironment =>
|
||||
|
@ -1,6 +1,5 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.DisableReason
|
||||
@ -14,6 +13,7 @@ import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.FakePlayer
|
||||
import net.minecraftforge.event.ForgeEventFactory
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
|
||||
import net.minecraftforge.fml.common.eventhandler.Event
|
||||
@ -42,6 +42,7 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b
|
||||
override def update(): Unit = {
|
||||
val world = player.getEntityWorld
|
||||
if (!world.isRemote) player match {
|
||||
case _: FakePlayer => // Nope
|
||||
case playerMP: EntityPlayerMP =>
|
||||
val now = world.getTotalWorldTime
|
||||
|
||||
|
@ -205,7 +205,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
}
|
||||
|
||||
val players = world.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect {
|
||||
case player: EntityPlayer => new PlayerChargeable(player)
|
||||
case player: EntityPlayer if api.Nanomachines.hasController(player) => new PlayerChargeable(player)
|
||||
}
|
||||
|
||||
// Only update list when we have to, keeps pointless block updates to a minimum.
|
||||
|
@ -319,7 +319,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
||||
|
||||
result(true)
|
||||
}
|
||||
else result(null, "not supported")
|
||||
else result(Unit, "not supported")
|
||||
}
|
||||
|
||||
@Callback(doc = """function(speed:number, x:number, y:number, z:number):boolean -- Set the rotation speed of the displayed hologram.""")
|
||||
@ -338,7 +338,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
||||
|
||||
result(true)
|
||||
}
|
||||
else result(null, "not supported")
|
||||
else result(Unit, "not supported")
|
||||
}
|
||||
|
||||
private def checkCoordinates(args: Arguments, idxX: Int = 0, idxY: Int = 1, idxZ: Int = 2) = {
|
||||
|
@ -152,7 +152,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
@Callback(doc = """function(minX:number, minY:number, minZ:number, maxX:number, maxY:number, maxZ:number, texture:string[, state:boolean=false][,tint:number]) -- Adds a shape to the printers configuration, optionally specifying whether it is for the off or on state.""")
|
||||
def addShape(context: Context, args: Arguments): Array[Object] = {
|
||||
if (data.stateOff.size > Settings.get.maxPrintComplexity || data.stateOn.size > Settings.get.maxPrintComplexity) {
|
||||
return result(null, "model too complex")
|
||||
return result(Unit, "model too complex")
|
||||
}
|
||||
val minX = (args.checkInteger(0) max 0 min 16) / 16f
|
||||
val minY = (args.checkInteger(1) max 0 min 16) / 16f
|
||||
@ -193,7 +193,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
||||
@Callback(doc = """function([count:number]):boolean -- Commit and begin printing the current configuration.""")
|
||||
def commit(context: Context, args: Arguments): Array[Object] = {
|
||||
if (!canPrint) {
|
||||
return result(null, "model invalid")
|
||||
return result(Unit, "model invalid")
|
||||
}
|
||||
limit = (args.optDouble(0, 1) max 0 min Integer.MAX_VALUE).toInt
|
||||
isActive = limit > 0
|
||||
|
@ -4,7 +4,7 @@ import li.cil.oc.server.component
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Transposer extends traits.Environment {
|
||||
val transposer = new component.Transposer(this)
|
||||
val transposer = new component.Transposer.Block(this)
|
||||
|
||||
def node = transposer.node
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package li.cil.oc.integration.appeng
|
||||
|
||||
import appeng.api.implementations.tiles.ISegmentedInventory
|
||||
import appeng.api.parts.IPartHost
|
||||
import li.cil.oc.api.internal.Database
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Context
|
||||
@ -9,7 +7,6 @@ import li.cil.oc.api.network.Component
|
||||
import li.cil.oc.api.network.ManagedEnvironment
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.ResultWrapper.result
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
@ -25,7 +22,7 @@ trait PartEnvironmentBase extends ManagedEnvironment {
|
||||
val slot = args.optSlot(config, 1, 0)
|
||||
val stack = config.getStackInSlot(slot)
|
||||
result(stack)
|
||||
case _ => result(null, "no matching part")
|
||||
case _ => result(Unit, "no matching part")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import li.cil.oc.integration.ManagedTileEntityEnvironment
|
||||
import li.cil.oc.util.ResultWrapper._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
import powercrystals.minefactoryreloaded.api.IDeepStorageUnit
|
||||
|
||||
object DriverDeepStorageUnit extends DriverTileEntity with EnvironmentAware {
|
||||
override def getTileEntityClass: Class[_] = classOf[IDeepStorageUnit]
|
||||
@ -31,7 +30,7 @@ object DriverDeepStorageUnit extends DriverTileEntity with EnvironmentAware {
|
||||
@Callback(doc = "function():int -- Get the maximum number of stored items.")
|
||||
def getStoredItemType(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
if (Settings.get.allowItemStackInspection) result(tileEntity.getStoredItemType)
|
||||
else result(null, "not enabled in config")
|
||||
else result(Unit, "not enabled in config")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
package li.cil.oc.integration.opencomputers
|
||||
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentAware
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.driver.item.HostAware
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.server.component
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
object DriverTransposer extends Item with HostAware with EnvironmentAware {
|
||||
override def worksWith(stack: ItemStack) = isOneOf(stack,
|
||||
api.Items.get(Constants.BlockName.Transposer))
|
||||
|
||||
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = new component.Transposer.Upgrade(host)
|
||||
|
||||
override def slot(stack: ItemStack) = Slot.Upgrade
|
||||
|
||||
override def providedEnvironment(stack: ItemStack) = classOf[component.Transposer.Upgrade]
|
||||
}
|
@ -105,7 +105,6 @@ object ModOpenComputers extends ModProxy {
|
||||
api.Driver.add(DriverDebugCard)
|
||||
api.Driver.add(DriverEEPROM)
|
||||
api.Driver.add(DriverFileSystem)
|
||||
api.Driver.add(DriverGeolyzer)
|
||||
api.Driver.add(DriverGraphicsCard)
|
||||
api.Driver.add(DriverInternetCard)
|
||||
api.Driver.add(DriverLinkedCard)
|
||||
@ -114,7 +113,6 @@ object ModOpenComputers extends ModProxy {
|
||||
api.Driver.add(DriverNetworkCard)
|
||||
api.Driver.add(DriverKeyboard)
|
||||
api.Driver.add(DriverRedstoneCard)
|
||||
api.Driver.add(DriverScreen)
|
||||
api.Driver.add(DriverTablet)
|
||||
api.Driver.add(DriverWirelessNetworkCard)
|
||||
|
||||
@ -122,6 +120,10 @@ object ModOpenComputers extends ModProxy {
|
||||
api.Driver.add(DriverContainerFloppy)
|
||||
api.Driver.add(DriverContainerUpgrade)
|
||||
|
||||
api.Driver.add(DriverGeolyzer)
|
||||
api.Driver.add(DriverScreen)
|
||||
api.Driver.add(DriverTransposer)
|
||||
|
||||
api.Driver.add(DriverUpgradeAngel)
|
||||
api.Driver.add(DriverUpgradeBattery)
|
||||
api.Driver.add(DriverUpgradeChunkloader)
|
||||
@ -145,6 +147,7 @@ object ModOpenComputers extends ModProxy {
|
||||
Constants.BlockName.Geolyzer,
|
||||
Constants.BlockName.Keyboard,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.BlockName.Transposer,
|
||||
Constants.ItemName.AngelUpgrade,
|
||||
Constants.ItemName.BatteryUpgradeTier1,
|
||||
Constants.ItemName.BatteryUpgradeTier2,
|
||||
@ -163,27 +166,28 @@ object ModOpenComputers extends ModProxy {
|
||||
Constants.ItemName.TractorBeamUpgrade,
|
||||
Constants.ItemName.LeashUpgrade)
|
||||
blacklistHost(classOf[internal.Drone],
|
||||
Constants.BlockName.Keyboard,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.BlockName.Transposer,
|
||||
Constants.ItemName.APUTier1,
|
||||
Constants.ItemName.APUTier2,
|
||||
Constants.ItemName.GraphicsCardTier1,
|
||||
Constants.ItemName.GraphicsCardTier2,
|
||||
Constants.ItemName.GraphicsCardTier3,
|
||||
Constants.BlockName.Keyboard,
|
||||
Constants.ItemName.NetworkCard,
|
||||
Constants.ItemName.RedstoneCardTier1,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.ItemName.AngelUpgrade,
|
||||
Constants.ItemName.CraftingUpgrade,
|
||||
Constants.ItemName.HoverUpgradeTier1,
|
||||
Constants.ItemName.HoverUpgradeTier2)
|
||||
blacklistHost(classOf[internal.Microcontroller],
|
||||
Constants.BlockName.Keyboard,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.ItemName.APUTier1,
|
||||
Constants.ItemName.APUTier2,
|
||||
Constants.ItemName.GraphicsCardTier1,
|
||||
Constants.ItemName.GraphicsCardTier2,
|
||||
Constants.ItemName.GraphicsCardTier3,
|
||||
Constants.BlockName.Keyboard,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.ItemName.AngelUpgrade,
|
||||
Constants.ItemName.ChunkloaderUpgrade,
|
||||
Constants.ItemName.CraftingUpgrade,
|
||||
@ -202,11 +206,13 @@ object ModOpenComputers extends ModProxy {
|
||||
Constants.ItemName.TractorBeamUpgrade,
|
||||
Constants.ItemName.LeashUpgrade)
|
||||
blacklistHost(classOf[internal.Robot],
|
||||
Constants.BlockName.Transposer,
|
||||
Constants.ItemName.LeashUpgrade)
|
||||
blacklistHost(classOf[internal.Tablet],
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.BlockName.Transposer,
|
||||
Constants.ItemName.NetworkCard,
|
||||
Constants.ItemName.RedstoneCardTier1,
|
||||
Constants.BlockName.ScreenTier1,
|
||||
Constants.ItemName.AngelUpgrade,
|
||||
Constants.ItemName.ChunkloaderUpgrade,
|
||||
Constants.ItemName.CraftingUpgrade,
|
||||
|
@ -6,6 +6,7 @@ import li.cil.oc.api.internal
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.common.entity
|
||||
import li.cil.oc.server.agent.ActivationType
|
||||
import li.cil.oc.server.agent.Player
|
||||
import li.cil.oc.util.BlockPosition
|
||||
@ -303,7 +304,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits
|
||||
player.side.getFrontOffsetZ * range)
|
||||
val hit = world.rayTraceBlocks(origin, target)
|
||||
player.closestEntity[Entity]() match {
|
||||
case Some(entity@(_: EntityLivingBase | _: EntityMinecart)) if hit == null || new Vec3(player.posX, player.posY, player.posZ).distanceTo(hit.hitVec) > player.getDistanceToEntity(entity) => new MovingObjectPosition(entity)
|
||||
case Some(entity@(_: EntityLivingBase | _: EntityMinecart | _: entity.Drone)) if hit == null || new Vec3(player.posX, player.posY, player.posZ).distanceTo(hit.hitVec) > player.getDistanceToEntity(entity) => new MovingObjectPosition(entity)
|
||||
case _ => hit
|
||||
}
|
||||
}
|
||||
|
@ -440,9 +440,9 @@ object DebugCard {
|
||||
tileEntity.markDirty()
|
||||
world.markBlockForUpdate(blockPos)
|
||||
result(true)
|
||||
case nbt => result(null, s"nbt tag compound expected, got '${NBTBase.NBT_TYPES(nbt.getId)}'")
|
||||
case nbt => result(Unit, s"nbt tag compound expected, got '${NBTBase.NBT_TYPES(nbt.getId)}'")
|
||||
}
|
||||
case _ => result(null, "no tile entity")
|
||||
case _ => result(Unit, "no tile entity")
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ object DebugCard {
|
||||
val removed = inventory.decrStackSize(slot, count)
|
||||
if (removed == null) result(0)
|
||||
else result(removed.stackSize)
|
||||
case _ => result(null, "no inventory")
|
||||
case _ => result(Unit, "no inventory")
|
||||
}
|
||||
}
|
||||
|
||||
@ -540,7 +540,7 @@ object DebugCard {
|
||||
val side = args.checkSide(5, EnumFacing.values: _*)
|
||||
world.getTileEntity(position) match {
|
||||
case handler: IFluidHandler => result(handler.fill(side, new FluidStack(fluid, amount), true))
|
||||
case _ => result(null, "no tank")
|
||||
case _ => result(Unit, "no tank")
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,7 +552,7 @@ object DebugCard {
|
||||
val side = args.checkSide(4, EnumFacing.values: _*)
|
||||
world.getTileEntity(position) match {
|
||||
case handler: IFluidHandler => result(handler.drain(side, amount, true))
|
||||
case _ => result(null, "no tank")
|
||||
case _ => result(Unit, "no tank")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,27 @@
|
||||
package li.cil.oc.server.component
|
||||
|
||||
import java.io.{BufferedWriter, FileNotFoundException, IOException, InputStream, OutputStreamWriter}
|
||||
import java.io.BufferedWriter
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net._
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.SocketChannel
|
||||
import java.util.concurrent.{Callable, ConcurrentLinkedQueue, ExecutionException, Future}
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.Future
|
||||
|
||||
import li.cil.oc.{OpenComputers, Settings, api}
|
||||
import li.cil.oc.api.machine.{Arguments, Callback, Context}
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.api.{Network, prefab}
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.api.prefab.AbstractValue
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ThreadPoolFactory
|
||||
@ -190,7 +202,7 @@ object InternetCard {
|
||||
if (checkConnected()) {
|
||||
val buffer = ByteBuffer.allocate(n)
|
||||
val read = channel.read(buffer)
|
||||
if (read == -1) result(null)
|
||||
if (read == -1) result(Unit)
|
||||
else result(buffer.array.view(0, read).toArray)
|
||||
}
|
||||
else result(Array.empty[Byte])
|
||||
@ -297,7 +309,7 @@ object InternetCard {
|
||||
def response(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
response match {
|
||||
case Some((code, message, headers)) => result(code, message, headers)
|
||||
case _ => result(null)
|
||||
case _ => result(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,7 +317,7 @@ object InternetCard {
|
||||
def read(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
val n = math.min(Settings.get.maxReadBuffer, math.max(0, args.optInteger(1, Int.MaxValue)))
|
||||
if (checkResponse()) {
|
||||
if (eof && queue.isEmpty) result(null)
|
||||
if (eof && queue.isEmpty) result(Unit)
|
||||
else {
|
||||
val buffer = ByteBuffer.allocate(n)
|
||||
var read = 0
|
||||
|
@ -2,68 +2,49 @@ package li.cil.oc.server.component
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.api.prefab
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.FluidUtils
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
import scala.language.existentials
|
||||
|
||||
class Transposer(val host: tileentity.Transposer) extends prefab.ManagedEnvironment with traits.WorldInventoryAnalytics with traits.WorldTankAnalytics {
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("transposer").
|
||||
withConnector().
|
||||
create()
|
||||
object Transposer {
|
||||
|
||||
override def position = BlockPosition(host)
|
||||
abstract class Common extends prefab.ManagedEnvironment with traits.WorldInventoryAnalytics with traits.WorldTankAnalytics with traits.InventoryTransfer {
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("transposer").
|
||||
withConnector().
|
||||
create()
|
||||
|
||||
override protected def checkSideForAction(args: Arguments, n: Int) = args.checkSide(n, EnumFacing.values: _*)
|
||||
override protected def checkSideForAction(args: Arguments, n: Int) =
|
||||
args.checkSide(n, EnumFacing.values: _*)
|
||||
|
||||
@Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number[, sourceSlot:number, sinkSlot:number]]):number -- Transfer some items between two inventories.""")
|
||||
def transferItem(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val sourceSide = checkSideForAction(args, 0)
|
||||
val sourcePos = position.offset(sourceSide)
|
||||
val sinkSide = checkSideForAction(args, 1)
|
||||
val sinkPos = position.offset(sinkSide)
|
||||
val count = args.optItemCount(2)
|
||||
|
||||
if (node.tryChangeBuffer(-Settings.get.transposerCost)) {
|
||||
ServerPacketSender.sendTransposerActivity(host)
|
||||
|
||||
if (args.count > 3) {
|
||||
val sourceSlot = args.checkSlot(InventoryUtils.inventoryAt(sourcePos).getOrElse(throw new IllegalArgumentException("no inventory")), 3)
|
||||
val sinkSlot = args.checkSlot(InventoryUtils.inventoryAt(sinkPos).getOrElse(throw new IllegalArgumentException("no inventory")), 4)
|
||||
|
||||
result(InventoryUtils.transferBetweenInventoriesSlotsAt(sourcePos, sourceSide.getOpposite, sourceSlot, sinkPos, Option(sinkSide.getOpposite), sinkSlot, count))
|
||||
}
|
||||
else result(InventoryUtils.transferBetweenInventoriesAt(sourcePos, sourceSide.getOpposite, sinkPos, Option(sinkSide.getOpposite), count))
|
||||
override def onTransferContents(): Option[String] = {
|
||||
if (node.tryChangeBuffer(-Settings.get.transposerCost)) None
|
||||
else Option("not enough energy")
|
||||
}
|
||||
else result(Unit, "not enough energy")
|
||||
}
|
||||
|
||||
@Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number]):number -- Transfer some items between two inventories.""")
|
||||
def transferFluid(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val sourceSide = checkSideForAction(args, 0)
|
||||
val sourcePos = position.offset(sourceSide)
|
||||
val sinkSide = checkSideForAction(args, 1)
|
||||
val sinkPos = position.offset(sinkSide)
|
||||
val count = args.optFluidCount(2)
|
||||
class Block(val host: tileentity.Transposer) extends Common {
|
||||
override def position = BlockPosition(host)
|
||||
|
||||
if (node.tryChangeBuffer(-Settings.get.transposerCost)) {
|
||||
ServerPacketSender.sendTransposerActivity(host)
|
||||
|
||||
val moved = FluidUtils.transferBetweenFluidHandlersAt(sourcePos, sourceSide.getOpposite, sinkPos, sinkSide.getOpposite, count)
|
||||
if (moved > 0) context.pause(moved / 1000 * 0.25) // Allow up to 4 buckets per second.
|
||||
result(moved > 0, moved)
|
||||
override def onTransferContents(): Option[String] = {
|
||||
val result = super.onTransferContents()
|
||||
if (result.isEmpty) ServerPacketSender.sendTransposerActivity(host)
|
||||
result
|
||||
}
|
||||
else result(Unit, "not enough energy")
|
||||
}
|
||||
|
||||
class Upgrade(val host: EnvironmentHost) extends Common {
|
||||
node.setVisibility(Visibility.Neighbors)
|
||||
|
||||
override def position = BlockPosition(host)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
package li.cil.oc.server.component.traits
|
||||
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.server.component._
|
||||
import li.cil.oc.util.ExtendedArguments._
|
||||
import li.cil.oc.util.FluidUtils
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
|
||||
trait InventoryTransfer extends traits.WorldAware with traits.SideRestricted {
|
||||
// Return None on success, else Some("failure reason")
|
||||
def onTransferContents(): Option[String]
|
||||
|
||||
@Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number[, sourceSlot:number[, sinkSlot:number]]]):number -- Transfer some items between two inventories.""")
|
||||
def transferItem(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val sourceSide = checkSideForAction(args, 0)
|
||||
val sourcePos = position.offset(sourceSide)
|
||||
val sinkSide = checkSideForAction(args, 1)
|
||||
val sinkPos = position.offset(sinkSide)
|
||||
val count = args.optItemCount(2)
|
||||
|
||||
onTransferContents() match {
|
||||
case Some(reason) =>
|
||||
result(Unit, reason)
|
||||
case _ =>
|
||||
if (args.count > 3) {
|
||||
val sourceSlot = args.checkSlot(InventoryUtils.inventoryAt(sourcePos).getOrElse(throw new IllegalArgumentException("no inventory")), 3)
|
||||
val sinkSlot = args.optSlot(InventoryUtils.inventoryAt(sinkPos).getOrElse(throw new IllegalArgumentException("no inventory")), 4, -1)
|
||||
|
||||
result(InventoryUtils.transferBetweenInventoriesSlotsAt(sourcePos, sourceSide.getOpposite, sourceSlot, sinkPos, Option(sinkSide.getOpposite), if (sinkSlot < 0) None else Option(sinkSlot), count))
|
||||
}
|
||||
else result(InventoryUtils.transferBetweenInventoriesAt(sourcePos, sourceSide.getOpposite, sinkPos, Option(sinkSide.getOpposite), count))
|
||||
}
|
||||
}
|
||||
|
||||
@Callback(doc = """function(sourceSide:number, sinkSide:number[, count:number]):number -- Transfer some items between two inventories.""")
|
||||
def transferFluid(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val sourceSide = checkSideForAction(args, 0)
|
||||
val sourcePos = position.offset(sourceSide)
|
||||
val sinkSide = checkSideForAction(args, 1)
|
||||
val sinkPos = position.offset(sinkSide)
|
||||
val count = args.optFluidCount(2)
|
||||
|
||||
onTransferContents() match {
|
||||
case Some(reason) =>
|
||||
result(Unit, reason)
|
||||
case _ =>
|
||||
val moved = FluidUtils.transferBetweenFluidHandlersAt(sourcePos, sourceSide.getOpposite, sinkPos, sinkSide.getOpposite, count)
|
||||
if (moved > 0) context.pause(moved / 1000 * 0.25) // Allow up to 4 buckets per second.
|
||||
result(moved > 0, moved)
|
||||
}
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
|
||||
val facing = checkSideForAction(args, 0)
|
||||
withInventory(facing, inventory => result(inventory.getStackInSlot(args.checkSlot(inventory, 1))))
|
||||
}
|
||||
else result(null, "not enabled in config")
|
||||
else result(Unit, "not enabled in config")
|
||||
|
||||
@Callback(doc = """function(side:number, slot:number, dbAddress:string, dbSlot:number):boolean -- Store an item stack description in the specified slot of the database with the specified address.""")
|
||||
def store(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
@ -80,6 +80,6 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ
|
||||
private def withInventory(side: EnumFacing, f: IInventory => Array[AnyRef]) =
|
||||
InventoryUtils.inventoryAt(position.offset(side)) match {
|
||||
case Some(inventory) if inventory.isUseableByPlayer(fakePlayer) && mayInteract(position.offset(side), side.getOpposite) => f(inventory)
|
||||
case _ => result(null, "no inventory")
|
||||
case _ => result(Unit, "no inventory")
|
||||
}
|
||||
}
|
||||
|
@ -249,9 +249,15 @@ object InventoryUtils {
|
||||
/**
|
||||
* Like <tt>transferBetweenInventories</tt> but moving between specific slots.
|
||||
*/
|
||||
def transferBetweenInventoriesSlots(source: IInventory, sourceSide: EnumFacing, sourceSlot: Int, sink: IInventory, sinkSide: Option[EnumFacing], sinkSlot: Int, limit: Int = 64) =
|
||||
extractFromInventorySlot(
|
||||
insertIntoInventorySlot(_, sink, sinkSide, sinkSlot, limit), source, sourceSide, sourceSlot, limit)
|
||||
def transferBetweenInventoriesSlots(source: IInventory, sourceSide: EnumFacing, sourceSlot: Int, sink: IInventory, sinkSide: Option[EnumFacing], sinkSlot: Option[Int], limit: Int = 64) =
|
||||
sinkSlot match {
|
||||
case Some(explicitSinkSlot) =>
|
||||
extractFromInventorySlot(
|
||||
insertIntoInventorySlot(_, sink, sinkSide, explicitSinkSlot, limit), source, sourceSide, sourceSlot, limit)
|
||||
case _ =>
|
||||
extractFromInventorySlot(
|
||||
insertIntoInventory(_, sink, sinkSide, limit), source, sourceSide, sourceSlot, limit)
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for calling <tt>transferBetweenInventories</tt> on inventories
|
||||
@ -266,7 +272,7 @@ object InventoryUtils {
|
||||
* Utility method for calling <tt>transferBetweenInventoriesSlots</tt> on inventories
|
||||
* in the world.
|
||||
*/
|
||||
def transferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[EnumFacing], sinkSlot: Int, limit: Int = 64) =
|
||||
def transferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[EnumFacing], sinkSlot: Option[Int], limit: Int = 64) =
|
||||
inventoryAt(sourcePos).exists(sourceInventory =>
|
||||
inventoryAt(sinkPos).exists(sinkInventory =>
|
||||
transferBetweenInventoriesSlots(sourceInventory, sourceSide, sourceSlot, sinkInventory, sinkSide, sinkSlot, limit)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user