expanded fake player class a bit to avoid weird things happening (such as the robots opening GUIs - hint: fun time!); added options on whether robots may activate blocks (levers, buttons) and whether onItemUseFirst should be called (disabled per default to get portal guns to work). the latter is a setting because it may cause issues in mods that actually use it

This commit is contained in:
Florian Nücke 2013-11-18 17:34:51 +01:00
parent cf6a3e372d
commit fbdac0760f
3 changed files with 117 additions and 47 deletions

View File

@ -16,12 +16,32 @@ object Config {
// ----------------------------------------------------------------------- //
var blockRenderId = 0
// ----------------------------------------------------------------------- //
var blockId = 3650
var blockSpecialId = 3651
var itemId = 4600
// ----------------------------------------------------------------------- //
// client
var maxScreenTextRenderDistance = 10.0
var screenTextFadeStartDistance = 8.0
var textLinearFiltering = false
// ----------------------------------------------------------------------- //
// power
var ignorePower = false
// power.buffer
var bufferConverter = 100.0
var bufferCapacitor = 50.0
var bufferPowerSupply = 50.0
// power.cost
var computerCost = 1.0
var gpuFillCost = 1.0 / 100
var gpuClearCost = 1.0 / 400
@ -34,23 +54,9 @@ object Config {
var wirelessCostPerRange = 1.0 / 20.0
// ----------------------------------------------------------------------- //
// server
var blockRenderId = 0
// ----------------------------------------------------------------------- //
var blockId = 3650
var blockSpecialId = 3651
var itemId = 4600
// ----------------------------------------------------------------------- //
var maxScreenTextRenderDistance = 10.0
var screenTextFadeStartDistance = 8.0
var textLinearFiltering = false
// ----------------------------------------------------------------------- //
// server.computer
var baseMemory = 0
var canComputersBeOwned = true
var maxUsernameLength = 32
@ -59,16 +65,25 @@ object Config {
var threads = 4
var timeout = 3.0
// server.filesystem
var fileCost = 512
var filesBuffered = true
var maxHandles = 16
var maxReadBuffer = 8 * 1024
// server.misc
var commandUser = "OpenComputers"
var maxScreenHeight = 6
var maxScreenWidth = 8
var maxWirelessRange = 400.0
// ----------------------------------------------------------------------- //
// robot
var callOnItemUseFirst = false
var allowActivateBlocks = true
var canAttackPlayers = false
// ----------------------------------------------------------------------- //
def load(file: File) = {

View File

@ -111,6 +111,8 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
val side = checkSideForAction(args, 0)
val count = checkOptionalItemCount(args, 1)
// TODO inventory, if available
// TODO player.dropitem with blah
result(robot.dropSlot(actualSlot(selectedSlot), count, side))
}
@ -118,6 +120,9 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
def place(context: Context, args: Arguments): Array[AnyRef] = {
val lookSide = checkSideForAction(args, 0)
val side = if (args.isInteger(1)) checkSide(args, 1) else lookSide
if (side.getOpposite == lookSide) {
throw new IllegalArgumentException("invalid side")
}
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
val player = robot.player(lookSide)
val stack = player.robotInventory.selectedItemStack
@ -139,7 +144,6 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
@LuaCallback("suck")
def suck(context: Context, args: Arguments): Array[AnyRef] = {
// Pick up items lying around.
val side = checkSideForAction(args, 0)
val count = checkOptionalItemCount(args, 1)
// TODO inventory, if available
@ -207,6 +211,9 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
def use(context: Context, args: Arguments): Array[AnyRef] = {
val lookSide = checkSideForAction(args, 0)
val side = if (args.isInteger(1)) checkSide(args, 1) else lookSide
if (side.getOpposite == lookSide) {
throw new IllegalArgumentException("invalid side")
}
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
val player = robot.player(lookSide)
player.setSneaking(sneaky)
@ -228,7 +235,6 @@ class Robot(val robot: tileentity.Robot) extends Computer(robot) {
@LuaCallback("turn")
def turn(context: Context, args: Arguments): Array[AnyRef] = {
// Turn in the specified direction.
val clockwise = args.checkBoolean(0)
if (clockwise) robot.rotate(ForgeDirection.UP)
else robot.rotate(ForgeDirection.DOWN)

View File

@ -1,9 +1,14 @@
package li.cil.oc.util
import li.cil.oc.Config
import li.cil.oc.common.tileentity.Robot
import net.minecraft.block.Block
import net.minecraft.entity.player.{EnumStatus, EntityPlayer}
import net.minecraft.entity.{EntityLivingBase, Entity}
import net.minecraft.item.ItemStack
import net.minecraft.util.ChunkCoordinates
import net.minecraft.potion.PotionEffect
import net.minecraft.util.{DamageSource, ChunkCoordinates}
import net.minecraft.world.World
import net.minecraftforge.common.{ForgeDirection, FakePlayer}
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action
import net.minecraftforge.event.{Event, ForgeEventFactory}
@ -16,10 +21,30 @@ class RobotPlayer(val robot: Robot) extends FakePlayer(robot.world, "OpenCompute
inventory = robotInventory
yOffset = 1f
// TODO override def getBoundingBox = super.getBoundingBox
override def getPlayerCoordinates = new ChunkCoordinates(robot.x, robot.y, robot.z)
// ----------------------------------------------------------------------- //
def updatePositionAndRotation(pitch: ForgeDirection) {
val offsetToGetPistonsToBePlacedProperly = pitch.offsetY * 0.83
setLocationAndAngles(
robot.x + 0.5,
robot.y - offsetToGetPistonsToBePlacedProperly,
robot.z + 0.5,
robot.yaw match {
case ForgeDirection.WEST => 90
case ForgeDirection.NORTH => 180
case ForgeDirection.EAST => 270
case _ => 0
}, pitch.offsetY * -90)
}
// ----------------------------------------------------------------------- //
// TODO override def canAttackWithItem = super.canAttackWithItem
// TODO override def attackTargetEntityWithCurrentItem(par1Entity: Entity)
def activateBlockOrUseItem(x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
val event = ForgeEventFactory.onPlayerInteract(this, Action.RIGHT_CLICK_BLOCK, x, y, z, side)
if (event.isCanceled) {
@ -29,15 +54,18 @@ class RobotPlayer(val robot: Robot) extends FakePlayer(robot.world, "OpenCompute
val world = robot.world
val stack = inventory.getCurrentItem
val item = if (stack != null) stack.getItem else null
if (item != null && item.onItemUseFirst(stack, this, world, x, y, z, side, hitX, hitY, hitZ)) {
if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, stack)
if (stack.stackSize <= 0) inventory.setInventorySlotContents(0, null)
return true
if (Config.callOnItemUseFirst) {
if (item != null && item.onItemUseFirst(stack, this, world, x, y, z, side, hitX, hitY, hitZ)) {
if (stack.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(this, stack)
if (stack.stackSize <= 0) inventory.setInventorySlotContents(0, null)
return true
}
}
val blockId = world.getBlockId(x, y, z)
val block = Block.blocksList(blockId)
val shouldActivate = block != null && (!isSneaking || (item == null || item.shouldPassSneakingClickToBlock(world, x, y, z)))
val canActivate = block != null && Config.allowActivateBlocks
val shouldActivate = canActivate && (!isSneaking || (item == null || item.shouldPassSneakingClickToBlock(world, x, y, z)))
val activated = shouldActivate && (event.useBlock == Event.Result.DENY ||
block.onBlockActivated(world, x, y, z, this, side, hitX, hitY, hitZ))
@ -78,27 +106,48 @@ class RobotPlayer(val robot: Robot) extends FakePlayer(robot.world, "OpenCompute
}
}
def updatePositionAndRotation(pitch: ForgeDirection) {
val offsetToGetPistonsToBePlacedProperly = pitch.offsetY * 0.83
posX = robot.x + 0.5
posY = robot.y + yOffset - offsetToGetPistonsToBePlacedProperly
posZ = robot.z + 0.5
rotationPitch = pitch.offsetY * -90
rotationYaw = robot.yaw match {
case ForgeDirection.WEST => 90
case ForgeDirection.NORTH => 180
case ForgeDirection.EAST => 270
case _ => 0
}
// ----------------------------------------------------------------------- //
prevPosX = posZ
prevPosY = posY
prevPosZ = posZ
prevRotationPitch = rotationPitch
cameraPitch = rotationPitch
prevCameraPitch = rotationPitch
prevRotationYaw = rotationYaw
cameraYaw = rotationYaw
prevCameraYaw = rotationYaw
override def swingItem() {
// TODO animation
}
override def canAttackPlayer(player: EntityPlayer) =
Config.canAttackPlayers && super.canAttackPlayer(player)
override def canEat(value: Boolean) = false
override def isPotionApplicable(effect: PotionEffect) = false
override def attackEntityAsMob(entity: Entity) = false
override def attackEntityFrom(source: DamageSource, damage: Float) = false
override def setItemInUse(stack: ItemStack, maxItemUseDuration: Int) {}
override def openGui(mod: AnyRef, modGuiId: Int, world: World, x: Int, y: Int, z: Int) {}
override def closeScreen() {}
override def heal(amount: Float) {}
override def setHealth(value: Float) {}
override def setDead() = isDead = true
override def onDeath(source: DamageSource) {}
override def setCurrentItemOrArmor(slot: Int, stack: ItemStack) {}
override def setRevengeTarget(entity: EntityLivingBase) {}
override def setLastAttacker(entity: Entity) {}
override def mountEntity(entity: Entity) {}
override def travelToDimension(dimension: Int) {}
override def sleepInBedAt(x: Int, y: Int, z: Int) = EnumStatus.OTHER_PROBLEM
override def interactWith(entity: Entity) = false // TODO Or do we want this?
}