This commit is contained in:
Florian Nücke 2014-01-12 23:15:19 +01:00
commit d19e0f641f
8 changed files with 77 additions and 29 deletions

View File

@ -29,7 +29,7 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledEmitter with IBund
override def isOutputEnabled_=(value: Boolean) = {
if (value != isOutputEnabled) {
if (!isOutputEnabled) {
if (!value) {
for (i <- 0 until _bundledOutput.length) {
for (j <- 0 until _bundledOutput(i).length) {
_bundledOutput(i)(j) = 0

View File

@ -31,7 +31,7 @@ trait RedstoneAware extends RotationAware with network.Environment with Persista
def isOutputEnabled_=(value: Boolean) = {
if (value != isOutputEnabled) {
_isOutputEnabled = value
if (!isOutputEnabled) {
if (!value) {
for (i <- 0 until _output.length) {
_output(i) = 0
}

View File

@ -455,7 +455,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
case _ => false
}
}
tryMergeTowards(width, 0) || tryMergeTowards(0, height) || tryMergeTowards(-1, 0) || tryMergeTowards(0, -1)
tryMergeTowards(0, height) || tryMergeTowards(0, -1) || tryMergeTowards(width, 0) || tryMergeTowards(-1, 0)
}
private def project(t: Screen) = {

View File

@ -120,8 +120,7 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard {
checkPacketSize(args.drop(1))
if (strength > 0) {
checkPower()
for ((card, distance) <- WirelessNetwork.computeReachableFrom(this)
if card.openPorts.contains(port)) {
for ((card, distance) <- WirelessNetwork.computeReachableFrom(this) if card.openPorts.contains(port)) {
card.node.sendToReachable("computer.signal",
Seq("modem_message", node.address, Int.box(port), Double.box(distance)) ++ args.drop(1): _*)
}

View File

@ -2,7 +2,7 @@ package li.cil.oc.server.component.robot
import li.cil.oc.Settings
import li.cil.oc.common.tileentity.Robot
import li.cil.oc.util.mods.PortalGun
import li.cil.oc.util.mods.{IndustrialCraft2, PortalGun}
import net.minecraft.block.{BlockPistonBase, BlockFluid, Block}
import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.{EnumStatus, EntityPlayer}
@ -153,14 +153,32 @@ class Player(val robot: Robot) extends EntityPlayer(robot.world, Settings.get.na
(!PortalGun.isPortalGun(stack) || PortalGun.isStandardPortalGun(stack)) && {
val oldSize = stack.stackSize
val oldDamage = if (stack != null) stack.getItemDamage else 0
val oldData = if (stack.hasTagCompound) stack.getTagCompound.copy() else null
val heldTicks = math.max(0, math.min(stack.getMaxItemUseDuration, (duration * 20).toInt))
val newStack = stack.useItemRightClick(world, this)
val newStack = if (IndustrialCraft2.isMiningLaser(stack)) {
// Fire the mining laser from a little bit ahead of us, to avoid hitting
// the robot itself.
val offset = facing
posX += offset.offsetX * 0.5
posY += offset.offsetY * 0.5
posZ += offset.offsetZ * 0.5
val result = stack.useItemRightClick(world, this)
posX -= offset.offsetX * 0.5
posY -= offset.offsetY * 0.5
posZ -= offset.offsetZ * 0.5
result
}
else stack.useItemRightClick(world, this)
if (isUsingItem) {
getItemInUse.onPlayerStoppedUsing(world, this, getItemInUse.getMaxItemUseDuration - heldTicks)
clearItemInUse()
}
robot.computer.pause(heldTicks / 20.0)
val stackChanged = newStack != stack || (newStack != null && (newStack.stackSize != oldSize || newStack.getItemDamage != oldDamage || PortalGun.isStandardPortalGun(stack)))
// These are functions to avoid null pointers if newStack is null.
def sizeOrDamageChanged = newStack.stackSize != oldSize || newStack.getItemDamage != oldDamage
def tagChanged = (oldData == null && newStack.hasTagCompound) || (oldData != null && !newStack.hasTagCompound) ||
(oldData != null && newStack.hasTagCompound && !oldData.equals(newStack.getTagCompound))
val stackChanged = newStack != stack || (newStack != null && (sizeOrDamageChanged || tagChanged || PortalGun.isStandardPortalGun(stack)))
if (newStack == stack && stack.stackSize > 0) {
tryRepair(stack, oldDamage)
}

View File

@ -61,9 +61,7 @@ object WirelessNetwork {
filter(_ != card).
map(zipWithDistance(card)).
filter(_._2 <= range * range).
map {
case (c, distance) => (c, Math.sqrt(distance))
}.
map { case (c, distance) => (c, Math.sqrt(distance)) }.
filter(isUnobstructed(card))
case _ => Iterable.empty[(WirelessNetworkCard, Double)] // Should not be possible.
}
@ -91,36 +89,49 @@ object WirelessNetwork {
// surplus strength left after crossing the distance between the two. If
// we reach a point where the surplus strength does not suffice we block
// the message.
val world = card.owner.worldObj
val pool = world.getWorldVec3Pool
// Unit vector from reference card (sender) to this one (receiver).
val dx = (card.owner.xCoord - reference.owner.xCoord) / distance
val dy = (card.owner.yCoord - reference.owner.yCoord) / distance
val dz = (card.owner.zCoord - reference.owner.zCoord) / distance
val origin = pool.getVecFromPool(reference.owner.xCoord, reference.owner.yCoord, reference.owner.zCoord)
val target = pool.getVecFromPool(card.owner.xCoord, card.owner.yCoord, card.owner.zCoord)
// Vector from reference card (sender) to this one (receiver).
val delta = origin.subtract(target)
val v = delta.normalize()
// Get the vectors that are orthogonal to the direction vector.
val up = if (v.xCoord == 0 && v.zCoord == 0) {
assert(v.yCoord != 0)
pool.getVecFromPool(1, 0, 0)
}
else {
pool.getVecFromPool(0, 1, 0)
}
val side = v.crossProduct(up)
val top = v.crossProduct(side)
// Accumulated obstructions and number of samples.
//val delta = v.lengthVector
var hardness = 0.0
val samples = Math.sqrt(gap).toInt
val samples = math.max(1, math.sqrt(gap).toInt)
val world = card.owner.worldObj
val ox = reference.owner.xCoord - (if (reference.owner.xCoord < 0) 2 else 1)
val oy = reference.owner.yCoord - (if (reference.owner.yCoord < 0) 2 else 1)
val oz = reference.owner.zCoord - (if (reference.owner.zCoord < 0) 2 else 1)
for (i <- 0 until samples) {
val sample = 0.5 + world.rand.nextDouble() * gap
val rGap = world.rand.nextDouble() * gap
// Adding some jitter to avoid only tracking the perfect line between
// two modems when they are diagonal to each other.
val x = (ox + world.rand.nextInt(3) + 0.5 + dx * sample).toInt
val y = (oy + world.rand.nextInt(3) + 0.5 + dy * sample).toInt
val z = (oz + world.rand.nextInt(3) + 0.5 + dz * sample).toInt
// two modems when they are diagonal to each other for example.
val rSide = world.rand.nextInt(3) - 1
val rTop = world.rand.nextInt(3) - 1
val x = (origin.xCoord + v.xCoord * rGap + side.xCoord * rSide + top.xCoord * rTop).toInt
val y = (origin.yCoord + v.yCoord * rGap + side.yCoord * rSide + top.yCoord * rTop).toInt
val z = (origin.zCoord + v.zCoord * rGap + side.zCoord * rSide + top.zCoord * rTop).toInt
Option(Block.blocksList(world.getBlockId(x, y, z))) match {
case Some(block) =>
hardness += block.blockHardness
case Some(block) => hardness += block.blockHardness
case _ =>
}
}
// Normalize and scale obstructions:
hardness *= gap.toDouble / samples.toDouble
hardness *= gap / samples
// Remaining signal strength.
val strength = reference.strength - gap

View File

@ -0,0 +1,20 @@
package li.cil.oc.util.mods
import cpw.mods.fml.common.Loader
import net.minecraft.item.ItemStack
object IndustrialCraft2 {
private lazy val miningLaser = try {
val clazz = Class.forName("ic2.core.Ic2Items")
val field = clazz.getField("miningLaser")
Option(field.get(null).asInstanceOf[ItemStack])
}
catch {
case _: Throwable => None
}
def isMiningLaser(stack: ItemStack) = stack != null && Loader.isModLoaded("IC2") && (miningLaser match {
case Some(laser) => laser.itemID == stack.itemID
case _ => false
})
}

View File

@ -4,7 +4,7 @@
"modid": "OpenComputers",
"name": "OpenComputers",
"description": "This mod adds modular computers and robots that can be programmed in Lua.",
"version": "1.1.0",
"version": "1.1.1",
"mcversion": "1.6.4",
"url": "https://github.com/MightyPirates/OpenComputers/wiki",
"authors": ["Florian 'Sangar' Nücke", "Johannes 'Lord Joda' Lohrer"],