diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index f70ba77dd..de652e164 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -16,6 +16,7 @@ tile.oc.chameliumBlock.name=Block of Chamelium tile.oc.charger.name=Charger tile.oc.disassembler.name=Disassembler tile.oc.diskDrive.name=Disk Drive +tile.oc.endstone.name=End Stone tile.oc.geolyzer.name=Geolyzer tile.oc.hologram1.name=Hologram Projector (Tier 1) tile.oc.hologram2.name=Hologram Projector (Tier 2) @@ -261,6 +262,7 @@ oc:tooltip.DiskDrive=Allows reading and writing floppies. Can be installed in ro oc:tooltip.Drone=Drones are light-weight, fast reconnaissance units with limited cargo space. oc:tooltip.DroneCase=This casing is used to build Drones in the assembler. It has room for a small amount of components and provides endstone-powered levitation. oc:tooltip.EEPROM=Small, programmable storage that contains the BIOS computers use to boot. +oc:tooltip.FakeEndstone=Almost as good as the real thing, even emulates its floatiness! oc:tooltip.Geolyzer=Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores. oc:tooltip.GraphicsCard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 oc:tooltip.InkCartridge=Used to refill ink in 3D printers. For mysterious reasons it does not have to remain in the printer. diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index d80b8745b..b3d54f0fa 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -36,25 +36,16 @@ luaBios { type: shapeless input: ["oc:eeprom", "oc:manual"] } -generic: [ - { - result: {block="minecraft:end_stone"} - input: [[enderPearl, sandstone, enderPearl] - [sandstone, blockCoal, sandstone] - [enderPearl, sandstone, enderPearl]] - output: 4 - } -] droneCase1 { - input: [[{block="minecraft:end_stone"}, compass, {block="minecraft:end_stone"}] + input: [["oc:stoneEndstone", compass, "oc:stoneEndstone"] ["oc:circuitChip1", "oc:microcontrollerCase1", "oc:circuitChip1"] - [{block="minecraft:end_stone"}, "oc:componentBus2", {block="minecraft:end_stone"}]] + ["oc:stoneEndstone", "oc:componentBus2", "oc:stoneEndstone"]] } droneCase2 { - input: [[{block="minecraft:end_stone"}, compass, {block="minecraft:end_stone"}] + input: [["oc:stoneEndstone", compass, "oc:stoneEndstone"] ["oc:circuitChip2", "oc:microcontrollerCase2", "oc:circuitChip2"] - [{block="minecraft:end_stone"}, "oc:componentBus3", {block="minecraft:end_stone"}]] + ["oc:stoneEndstone", "oc:componentBus3", "oc:stoneEndstone"]] } microcontrollerCase1 { input: [[nuggetIron, "oc:circuitChip1", nuggetIron] @@ -374,6 +365,13 @@ chameliumBlock { ["oc:chamelium", "oc:chamelium", "oc:chamelium"], ["oc:chamelium", "oc:chamelium", "oc:chamelium"]] } + +endstone { + input: [[enderPearl, "oc:chameliumBlock", enderPearl] + ["oc:chameliumBlock", enderPearl, "oc:chameliumBlock"] + [enderPearl, "oc:chameliumBlock", enderPearl]] + output: 4 +} inkCartridgeEmpty { input: [[nuggetIron, dispenser, nuggetIron], ["oc:materialTransistor", bucket, "oc:materialTransistor"], diff --git a/src/main/scala/li/cil/oc/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index 992937a4e..1a591e37b 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -18,6 +18,7 @@ object Constants { final val Charger = "charger" final val Disassembler = "disassembler" final val DiskDrive = "diskDrive" + final val Endstone = "endstone" final val Geolyzer = "geolyzer" final val HologramTier1 = "hologram1" final val HologramTier2 = "hologram2" diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala index aec3020d4..1ca918ed8 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala @@ -353,8 +353,11 @@ object RobotRenderer extends TileEntitySpecialRenderer { GL11.glTranslatef(0, -8 * 0.0625F - 0.0078125F, -0.5F) if (robot.isAnimatingSwing) { - val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toDouble - GL11.glRotatef((Math.sin(remaining * Math.PI) * 45).toFloat, 1, 0, 0) + val wantedTicksPerCycle = 10 + val cycles = math.max(robot.animationTicksTotal / wantedTicksPerCycle, 1) + val ticksPerCycle = robot.animationTicksTotal / cycles + val remaining = (robot.animationTicksLeft - f) / ticksPerCycle.toDouble + GL11.glRotatef((Math.sin((remaining - remaining.toInt) * Math.PI) * 45).toFloat, 1, 0, 0) } val item = stack.getItem diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 60af034f1..f122b6f30 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -60,6 +60,9 @@ class Proxy { // oredict entry, but not normal obsidian, breaking some recipes. OreDictionary.registerOre("obsidian", net.minecraft.init.Blocks.obsidian) + // To still allow using normal endstone for crafting drones. + OreDictionary.registerOre("oc:stoneEndstone", net.minecraft.init.Blocks.end_stone) + OpenComputers.log.info("Initializing OpenComputers API.") api.CreativeTab.instance = CreativeTab diff --git a/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala b/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala index 810336910..bd773e942 100644 --- a/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala +++ b/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.block import li.cil.oc.util.Color +import net.minecraft.block.material.Material import net.minecraft.block.properties.PropertyEnum import net.minecraft.block.state.BlockState import net.minecraft.block.state.IBlockState @@ -12,7 +13,7 @@ object ChameliumBlock { final val Color = PropertyEnum.create("color", classOf[EnumDyeColor]) } -class ChameliumBlock extends SimpleBlock { +class ChameliumBlock extends SimpleBlock(Material.rock) { setDefaultState(blockState.getBaseState.withProperty(ChameliumBlock.Color, EnumDyeColor.BLACK)) @SideOnly(Side.CLIENT) diff --git a/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala b/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala new file mode 100644 index 000000000..5f0f11b93 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala @@ -0,0 +1,8 @@ +package li.cil.oc.common.block + +import net.minecraft.block.material.Material + +class FakeEndstone extends SimpleBlock(Material.rock) { + setHardness(3) + setResistance(15) +} diff --git a/src/main/scala/li/cil/oc/common/block/Keyboard.scala b/src/main/scala/li/cil/oc/common/block/Keyboard.scala index 246e4472a..391b80891 100644 --- a/src/main/scala/li/cil/oc/common/block/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/block/Keyboard.scala @@ -6,6 +6,7 @@ import li.cil.oc.api import li.cil.oc.common.tileentity import li.cil.oc.util.ExtendedEnumFacing._ import net.minecraft.block.Block +import net.minecraft.block.material.Material import net.minecraft.block.state.IBlockState import net.minecraft.entity.player.EntityPlayer import net.minecraft.util.AxisAlignedBB @@ -15,7 +16,7 @@ import net.minecraft.world.IBlockAccess import net.minecraft.world.World import org.lwjgl.opengl.GL11 -class Keyboard extends SimpleBlock with traits.OmniRotatable { +class Keyboard extends SimpleBlock(Material.rock) with traits.OmniRotatable { setLightOpacity(0) // For Immibis Microblock support. diff --git a/src/main/scala/li/cil/oc/common/init/Blocks.scala b/src/main/scala/li/cil/oc/common/init/Blocks.scala index e15a8af9b..c59427f83 100644 --- a/src/main/scala/li/cil/oc/common/init/Blocks.scala +++ b/src/main/scala/li/cil/oc/common/init/Blocks.scala @@ -70,5 +70,8 @@ object Blocks { Items.registerBlock(new Print(), Constants.BlockName.Print) Items.registerBlock(new RobotAfterimage(), Constants.BlockName.RobotAfterimage) Items.registerBlock(new RobotProxy(), Constants.BlockName.Robot) + + // v1.5.10 + Recipes.addBlock(new FakeEndstone(), Constants.BlockName.Endstone, "oc:stoneEndstone") } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala index e0a42f004..3c050eeb7 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala @@ -353,7 +353,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot } def setAnimateSwing(ticks: Int) { - animationTicksTotal = ticks + animationTicksTotal = math.max(ticks, 5) prepareForAnimation() swingingTool = true } diff --git a/src/main/scala/li/cil/oc/server/agent/Player.scala b/src/main/scala/li/cil/oc/server/agent/Player.scala index 13872f754..0b75437eb 100644 --- a/src/main/scala/li/cil/oc/server/agent/Player.scala +++ b/src/main/scala/li/cil/oc/server/agent/Player.scala @@ -8,6 +8,7 @@ import li.cil.oc.Settings import li.cil.oc.api.event._ import li.cil.oc.api.internal import li.cil.oc.api.network.Connector +import li.cil.oc.common.EventHandler import li.cil.oc.integration.Mods import li.cil.oc.integration.util.PortalGun import li.cil.oc.integration.util.TinkersConstruct @@ -273,7 +274,7 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc }, repair = false) } - def clickBlock(pos: BlockPos, side: EnumFacing): Double = { + def clickBlock(pos: BlockPos, side: EnumFacing, immediate: Boolean = false): Double = { callUsingItemInSlot(agent.equipmentInventory, 0, stack => { if (shouldCancel(() => ForgeEventFactory.onPlayerInteract(this, Action.LEFT_CLICK_BLOCK, world, pos, side))) { return 0 @@ -350,6 +351,13 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc return 0 } + if (!immediate) { + EventHandler.schedule(() => new DamageOverTime(this, pos, side, (adjustedBreakTime * 20).toInt).tick()) + return adjustedBreakTime + } + + world.sendBlockBreakProgress(-1, pos, -1) + world.playAuxSFXAtEntity(this, 2001, pos, Block.getIdFromBlock(block) + (metadata << 12)) if (stack != null) { @@ -542,4 +550,34 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc override def displayGUIHorse(horse: EntityHorse, inventory: IInventory) {} override def openEditSign(signTile: TileEntitySign) {} + + // ----------------------------------------------------------------------- // + + class DamageOverTime(val player: Player, val pos: BlockPos, val side: EnumFacing, val ticksTotal: Int) { + val world = player.world + var ticks = 0 + var lastDamageSent = 0 + + def tick(): Unit = { + // Cancel if the agent stopped or our action is invalidated some other way. + if (world != player.world || !world.isBlockLoaded(pos) || world.isAirBlock(pos) || !player.agent.machine.isRunning) { + world.sendBlockBreakProgress(-1, pos, -1) + return + } + + val damage = 10 * ticks / math.max(ticksTotal, 1) + if (damage >= 10) { + player.clickBlock(pos, side, immediate = true) + } + else { + ticks += 1 + if (damage != lastDamageSent) { + lastDamageSent = damage + world.sendBlockBreakProgress(-1, pos, damage) + } + EventHandler.schedule(() => tick()) + } + } + } + }