Improved interaction of drones with water and other external forces.

This commit is contained in:
Florian Nücke 2014-12-16 00:36:18 +01:00
parent 768269054e
commit ebfa43df2b

View File

@ -20,8 +20,10 @@ import li.cil.oc.common.inventory.Inventory
import li.cil.oc.server.component import li.cil.oc.server.component
import li.cil.oc.util.BlockPosition import li.cil.oc.util.BlockPosition
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.util.ExtendedWorld._
import li.cil.oc.util.InventoryUtils import li.cil.oc.util.InventoryUtils
import li.cil.oc.util.ItemUtils import li.cil.oc.util.ItemUtils
import net.minecraft.block.material.Material
import net.minecraft.entity.Entity import net.minecraft.entity.Entity
import net.minecraft.entity.item.EntityItem import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.EntityPlayer import net.minecraft.entity.player.EntityPlayer
@ -30,6 +32,7 @@ import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.MovingObjectPosition import net.minecraft.util.MovingObjectPosition
import net.minecraft.util.Vec3 import net.minecraft.util.Vec3
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.util.ForgeDirection
class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone { class Drone(val world: World) extends Entity(world) with MachineHost with internal.Drone {
// Some basic constants. // Some basic constants.
@ -39,7 +42,8 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
val maxAcceleration = 0.1f val maxAcceleration = 0.1f
val maxVelocity = 0.4f val maxVelocity = 0.4f
val maxInventorySize = 8 val maxInventorySize = 8
setSize(1, 6 / 16f) setSize(12 / 16f, 6 / 16f)
isImmuneToFire = true
// Rendering stuff, purely eyecandy. // Rendering stuff, purely eyecandy.
val targetFlapAngles = Array.fill(4, 2)(0f) val targetFlapAngles = Array.fill(4, 2)(0f)
@ -187,44 +191,26 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
} }
def isRunning = dataWatcher.getWatchableObjectByte(2) != 0 def isRunning = dataWatcher.getWatchableObjectByte(2) != 0
def targetX = dataWatcher.getWatchableObjectFloat(3) def targetX = dataWatcher.getWatchableObjectFloat(3)
def targetY = dataWatcher.getWatchableObjectFloat(4) def targetY = dataWatcher.getWatchableObjectFloat(4)
def targetZ = dataWatcher.getWatchableObjectFloat(5) def targetZ = dataWatcher.getWatchableObjectFloat(5)
def targetAcceleration = dataWatcher.getWatchableObjectFloat(6) def targetAcceleration = dataWatcher.getWatchableObjectFloat(6)
def selectedSlot = dataWatcher.getWatchableObjectByte(7) & 0xFF def selectedSlot = dataWatcher.getWatchableObjectByte(7) & 0xFF
def globalBuffer = dataWatcher.getWatchableObjectInt(8) def globalBuffer = dataWatcher.getWatchableObjectInt(8)
def globalBufferSize = dataWatcher.getWatchableObjectInt(9) def globalBufferSize = dataWatcher.getWatchableObjectInt(9)
def statusText = dataWatcher.getWatchableObjectString(10) def statusText = dataWatcher.getWatchableObjectString(10)
def inventorySize = dataWatcher.getWatchableObjectByte(11) & 0xFF def inventorySize = dataWatcher.getWatchableObjectByte(11) & 0xFF
def setRunning(value: Boolean) = dataWatcher.updateObject(2, byte2Byte(if (value) 1: Byte else 0: Byte)) def setRunning(value: Boolean) = dataWatcher.updateObject(2, byte2Byte(if (value) 1: Byte else 0: Byte))
// Round target values to low accuracy to avoid floating point errors accumulating. // Round target values to low accuracy to avoid floating point errors accumulating.
def targetX_=(value: Float): Unit = dataWatcher.updateObject(3, float2Float(math.round(value * 5) / 5f)) def targetX_=(value: Float): Unit = dataWatcher.updateObject(3, float2Float(math.round(value * 4) / 4f))
def targetY_=(value: Float): Unit = dataWatcher.updateObject(4, float2Float(math.round(value * 4) / 4f))
def targetY_=(value: Float): Unit = dataWatcher.updateObject(4, float2Float(math.round(value * 5) / 5f)) def targetZ_=(value: Float): Unit = dataWatcher.updateObject(5, float2Float(math.round(value * 4) / 4f))
def targetZ_=(value: Float): Unit = dataWatcher.updateObject(5, float2Float(math.round(value * 5) / 5f))
def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.max(0, math.min(maxAcceleration, value)))) def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.max(0, math.min(maxAcceleration, value))))
def selectedSlot_=(value: Int) = dataWatcher.updateObject(7, byte2Byte(value.toByte)) def selectedSlot_=(value: Int) = dataWatcher.updateObject(7, byte2Byte(value.toByte))
def globalBuffer_=(value: Int) = dataWatcher.updateObject(8, int2Integer(value)) def globalBuffer_=(value: Int) = dataWatcher.updateObject(8, int2Integer(value))
def globalBufferSize_=(value: Int) = dataWatcher.updateObject(9, int2Integer(value)) def globalBufferSize_=(value: Int) = dataWatcher.updateObject(9, int2Integer(value))
def statusText_=(value: String) = dataWatcher.updateObject(10, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse("")) def statusText_=(value: String) = dataWatcher.updateObject(10, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse(""))
def inventorySize_=(value: Int) = dataWatcher.updateObject(11, byte2Byte(value.toByte)) def inventorySize_=(value: Int) = dataWatcher.updateObject(11, byte2Byte(value.toByte))
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@ -257,11 +243,11 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
} }
} }
override def onEntityUpdate() { override def onUpdate() {
super.onEntityUpdate() super.onUpdate()
if (!world.isRemote) { if (!world.isRemote) {
if (isInWater) { if (isInsideOfMaterial(Material.water) || isInsideOfMaterial(Material.lava)) {
// We're not water-proof! // We're not water-proof!
machine.stop() machine.stop()
} }
@ -330,12 +316,28 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
// No power, free fall: engage! // No power, free fall: engage!
motionY -= gravity motionY -= gravity
} }
prevPosX = posX
prevPosY = posY
prevPosZ = posZ
noClip = func_145771_j(posX, (boundingBox.minY + boundingBox.maxY) / 2, posZ)
moveEntity(motionX, motionY, motionZ) moveEntity(motionX, motionY, motionZ)
// Make sure we don't get infinitely faster. // Make sure we don't get infinitely faster.
motionX *= drag if (isRunning) {
motionY *= drag motionX *= drag
motionZ *= drag motionY *= drag
motionZ *= drag
}
else {
val groundDrag = worldObj.getBlock(BlockPosition(this).offset(ForgeDirection.DOWN)).slipperiness * drag
motionX *= groundDrag
motionY *= drag
motionZ *= groundDrag
if (onGround) {
motionY *= -0.5
}
}
} }
override def hitByEntity(entity: Entity) = { override def hitByEntity(entity: Entity) = {
@ -347,9 +349,9 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
else else
machine.signal("hit", double2Double(direction.xCoord), double2Double(direction.zCoord), double2Double(direction.yCoord)) machine.signal("hit", double2Double(direction.xCoord), double2Double(direction.zCoord), double2Double(direction.yCoord))
} }
motionX -= direction.xCoord motionX -= direction.xCoord * 0.5f
motionY -= direction.yCoord motionY -= direction.yCoord * 0.5f
motionZ -= direction.zCoord motionZ -= direction.zCoord * 0.5f
} }
super.hitByEntity(entity) super.hitByEntity(entity)
} }
@ -372,6 +374,11 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def handleWaterMovement() = {
inWater = worldObj.handleMaterialAcceleration(boundingBox, Material.water, this)
inWater
}
override def readEntityFromNBT(nbt: NBTTagCompound) { override def readEntityFromNBT(nbt: NBTTagCompound) {
info.load(nbt.getCompoundTag("info")) info.load(nbt.getCompoundTag("info"))
inventorySize = computeInventorySize() inventorySize = computeInventorySize()