diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/init.lua b/src/main/resources/assets/opencomputers/loot/OpenOS/init.lua index 5640b476e..63d22ff03 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/init.lua +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/init.lua @@ -1,4 +1,6 @@ do + _G._OSVERSION = "OpenOS 1.2" + local component = component local computer = computer local unicode = unicode diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua index 87be3e92e..d81190e50 100644 --- a/src/main/resources/assets/opencomputers/lua/kernel.lua +++ b/src/main/resources/assets/opencomputers/lua/kernel.lua @@ -249,7 +249,6 @@ sandbox = { traceback = debug.traceback }, - _OSVERSION = "OpenOS 1.2", checkArg = checkArg } sandbox._G = sandbox @@ -622,7 +621,7 @@ local function bootstrap() end end if not init then - error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or "")) + error("no bootable medium found" .. (reason and (": " .. tostring(reason)) or ""), 0) end return coroutine.create(init), {n=0} diff --git a/src/main/resources/reference.conf b/src/main/resources/reference.conf index bbfb78946..813fb4b05 100644 --- a/src/main/resources/reference.conf +++ b/src/main/resources/reference.conf @@ -820,5 +820,8 @@ opencomputers { # on computers' save and load performance, so you should not enable # this unless you're asked to. verbosePersistenceErrors: false + + # Whether to not show your special thinger (if you have one you know it). + hideOwnSpecial: false } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index eda9c3763..5a78d572f 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -210,6 +210,7 @@ class Settings(config: Config) { val geolyzerRange = config.getInt("misc.geolyzerRange") val disassembleAllTheThings = config.getBoolean("misc.disassembleAllTheThings") val disassemblerBreakChance = config.getDouble("misc.disassemblerBreakChance") max 0 min 1 + val hideOwnPet = config.getBoolean("misc.hideOwnSpecial") } object Settings { diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index b5fa9a62f..97f166fd6 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -4,6 +4,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent import cpw.mods.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent import li.cil.oc.{Localization, Settings} import li.cil.oc.api.component +import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits._ import li.cil.oc.common.{PacketType, PacketHandler => CommonPacketHandler} @@ -40,6 +41,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.HologramPowerChange => onHologramPowerChange(p) case PacketType.HologramScale => onHologramScale(p) case PacketType.HologramSet => onHologramSet(p) + case PacketType.PetVisibility => onPetVisibility(p) case PacketType.PowerState => onPowerState(p) case PacketType.RedstoneState => onRedstoneState(p) case PacketType.RobotAnimateSwing => onRobotAnimateSwing(p) @@ -178,6 +180,19 @@ object PacketHandler extends CommonPacketHandler { case _ => // Invalid packet. } + def onPetVisibility(p: PacketParser) { + val count = p.readInt() + for (i <- 0 until count) { + val name = p.readUTF() + if (p.readBoolean()) { + PetRenderer.hidden -= name + } + else { + PetRenderer.hidden += name + } + } + } + def onPowerState(p: PacketParser) = p.readTileEntity[PowerInformation]() match { case Some(t) => diff --git a/src/main/scala/li/cil/oc/client/PacketSender.scala b/src/main/scala/li/cil/oc/client/PacketSender.scala index 515a4f0f1..5aad0d07e 100644 --- a/src/main/scala/li/cil/oc/client/PacketSender.scala +++ b/src/main/scala/li/cil/oc/client/PacketSender.scala @@ -1,5 +1,6 @@ package li.cil.oc.client +import li.cil.oc.Settings import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.Computer import li.cil.oc.common.{CompressedPacketBuilder, PacketBuilder, PacketType} @@ -100,6 +101,14 @@ object PacketSender { pb.sendToServer() } + def sendPetVisibility() { + val pb = new PacketBuilder(PacketType.PetVisibility) + + pb.writeBoolean(!Settings.get.hideOwnPet) + + pb.sendToServer() + } + def sendRobotAssemblerStart(t: RobotAssembler) { val pb = new PacketBuilder(PacketType.RobotAssemblerStart) diff --git a/src/main/scala/li/cil/oc/client/gui/TextBuffer.scala b/src/main/scala/li/cil/oc/client/gui/TextBuffer.scala index d4599f500..14218aad0 100644 --- a/src/main/scala/li/cil/oc/client/gui/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/client/gui/TextBuffer.scala @@ -24,8 +24,9 @@ trait TextBuffer extends GuiScreen { protected def bufferY: Int - protected var currentWidth, currentHeight = -1 + protected var guiSizeChanged = false + protected var currentWidth, currentHeight = -1 private var showKeyboardMissing = 0L @@ -37,6 +38,7 @@ trait TextBuffer extends GuiScreen { super.initGui() BufferRenderer.init(Minecraft.getMinecraft.renderEngine) Keyboard.enableRepeatEvents(true) + guiSizeChanged = true } override def onGuiClosed() = { @@ -58,7 +60,7 @@ trait TextBuffer extends GuiScreen { currentWidth = 0 currentHeight = 0 } - scale = changeSize(currentWidth, currentHeight, oldWidth != currentWidth || oldHeight != currentHeight) + scale = changeSize(currentWidth, currentHeight, guiSizeChanged || oldWidth != currentWidth || oldHeight != currentHeight) RenderState.checkError(getClass.getName + ".drawBufferLayer: entering (aka: wasntme)") diff --git a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala index 39fa899fe..92c77190f 100644 --- a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala @@ -13,9 +13,12 @@ import net.minecraftforge.client.event.RenderPlayerEvent import org.lwjgl.opengl.{GL11, GL12} import scala.collection.convert.WrapAsScala._ +import scala.collection.mutable object PetRenderer { - private val entitledPlayers = Map("Kethtar" -> (0.3, 0.9, 0.6)) + val hidden = mutable.Set.empty[String] + + private val entitledPlayers = Map("Kethtar" ->(0.3, 0.9, 0.6)) private val petLocations = com.google.common.cache.CacheBuilder.newBuilder(). expireAfterAccess(5, TimeUnit.SECONDS). @@ -27,7 +30,7 @@ object PetRenderer { @SubscribeEvent def onPlayerRender(e: RenderPlayerEvent.Pre) { val name = e.entityPlayer.getCommandSenderName - if (!entitledPlayers.contains(name)) return + if (hidden.contains(name) || !entitledPlayers.contains(name)) return rendering = Some(entitledPlayers(name)) val worldTime = e.entityPlayer.getEntityWorld.getWorldTime diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 64cddb502..7075a1b32 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -4,18 +4,22 @@ import codechicken.multipart.TMultiPart import cpw.mods.fml.common.eventhandler.SubscribeEvent import cpw.mods.fml.common.gameevent.PlayerEvent._ import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent +import cpw.mods.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent import cpw.mods.fml.common.{FMLCommonHandler, Optional} import ic2.api.energy.event.{EnergyTileLoadEvent, EnergyTileUnloadEvent} import li.cil.oc._ import li.cil.oc.api.Network +import li.cil.oc.client.renderer.PetRenderer +import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.tileentity.traits.power +import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.LuaStateFactory import li.cil.oc.util.mods.{Mods, ProjectRed} +import net.minecraft.client.Minecraft import net.minecraft.entity.player.EntityPlayerMP import net.minecraft.item.ItemStack import net.minecraft.server.MinecraftServer import net.minecraft.tileentity.TileEntity -import net.minecraft.util.{ChatComponentText, ChatComponentTranslation} import net.minecraftforge.common.MinecraftForge import org.apache.logging.log4j.Level @@ -69,22 +73,19 @@ object EventHandler { if (FMLCommonHandler.instance.getEffectiveSide.isServer) e.player match { case player: EntityPlayerMP => if (!LuaStateFactory.isAvailable) { - player.addChatMessage(new ChatComponentText("§aOpenComputers§f: ").appendSibling( - new ChatComponentTranslation(Settings.namespace + "gui.Chat.WarningLuaFallback"))) + player.addChatMessage(Localization.Chat.WarningLuaFallback) } if (Mods.ProjectRed.isAvailable && !ProjectRed.isAPIAvailable) { - player.addChatMessage(new ChatComponentText("§aOpenComputers§f: ").appendSibling( - new ChatComponentTranslation(Settings.namespace + "gui.Chat.WarningProjectRed"))) + player.addChatMessage(Localization.Chat.WarningProjectRed) } if (!Settings.get.pureIgnorePower && Settings.get.ignorePower) { - player.addChatMessage(new ChatComponentText("§aOpenComputers§f: ").appendSibling( - new ChatComponentTranslation(Settings.namespace + "gui.Chat.WarningPower"))) + player.addChatMessage(Localization.Chat.WarningPower) } OpenComputers.tampered match { - case Some(event) => player.addChatMessage(new ChatComponentText("§aOpenComputers§f: ").appendSibling( - new ChatComponentTranslation(Settings.namespace + "gui.Chat.WarningFingerprint", event.expectedFingerprint, event.fingerprints.toArray.mkString(", ")))) + case Some(event) => player.addChatMessage(Localization.Chat.WarningFingerprint(event)) case _ => } + ServerPacketSender.sendPetVisibility(None, Some(player)) // Do update check in local games and for OPs. if (!MinecraftServer.getServer.isDedicatedServer || MinecraftServer.getServer.getConfigurationManager.isPlayerOpped(player.getCommandSenderName)) { UpdateCheck.checkForPlayer(player) @@ -93,6 +94,15 @@ object EventHandler { } } + @SubscribeEvent + def clientLoggedIn(e: ClientConnectedToServerEvent) { + PetRenderer.hidden.clear() + if (Settings.get.hideOwnPet) { + PetRenderer.hidden += Minecraft.getMinecraft.thePlayer.getCommandSenderName + } + ClientPacketSender.sendPetVisibility() + } + lazy val navigationUpgrade = api.Items.get("navigationUpgrade") @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index 7e7bdf8d2..391731975 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -15,6 +15,7 @@ object PacketType extends Enumeration { HologramPowerChange, HologramScale, HologramSet, + PetVisibility, // Goes both ways. PowerState, RedstoneState, RobotAnimateSwing, diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index d7da0eea1..6881e8b89 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -140,8 +140,9 @@ class Proxy { // Don't allow driver registration after this point, to avoid issues. driver.Registry.locked = true - FMLCommonHandler.instance().bus().register(EventHandler) - FMLCommonHandler.instance().bus().register(SimpleComponentTickHandler.Instance) + FMLCommonHandler.instance.bus.register(EventHandler) + FMLCommonHandler.instance.bus.register(SimpleComponentTickHandler.Instance) + MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(WirelessNetwork) MinecraftForge.EVENT_BUS.register(SaveHandler) } diff --git a/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala b/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala index ff2ee7b0c..765d3d724 100644 --- a/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala @@ -18,7 +18,13 @@ object ChunkloaderUpgradeHandler extends LoadingCallback { override def ticketsLoaded(tickets: util.List[Ticket], world: World) { for (ticket <- tickets) { - restoredTickets += ticket.getModData.getString("address") -> ticket + val data = ticket.getModData + restoredTickets += data.getString("address") -> ticket + if (data.hasKey("x") && data.hasKey("z")) { + val x = data.getInteger("x") + val z = data.getInteger("z") + ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(x, z)) + } } } @@ -35,9 +41,12 @@ object ChunkloaderUpgradeHandler extends LoadingCallback { restoredTickets.clear() } - // TODO it might be necessary to use pre move to force load the target chunk + // Note: it might be necessary to use pre move to force load the target chunk // in case the robot moves across a chunk border into an otherwise unloaded - // chunk (I think it would just fail to move otherwise) + // chunk (I think it would just fail to move otherwise). + // Update 2014-06-21: did some testing, seems not to be necessary. My guess + // is that the access to the block in the direction the robot moves causes + // the chunk it might move into to get loaded. @SubscribeEvent def onMove(e: RobotMoveEvent.Post) { @@ -57,6 +66,8 @@ object ChunkloaderUpgradeHandler extends LoadingCallback { } ForgeChunkManager.forceChunk(ticket, robotChunk) ticket.getModData.setString("address", loader.node.address) + ticket.getModData.setInteger("x", robotChunk.chunkXPos) + ticket.getModData.setInteger("z", robotChunk.chunkZPos) }) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala index ca977f772..a480111a2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala @@ -1,8 +1,8 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings -import li.cil.oc.api.{driver, network} import li.cil.oc.api.network.{Connector, SidedEnvironment} +import li.cil.oc.api.{driver, network} import li.cil.oc.common.EventHandler import li.cil.oc.util.ExtendedNBT._ import net.minecraft.nbt.NBTTagCompound diff --git a/src/main/scala/li/cil/oc/server/PacketHandler.scala b/src/main/scala/li/cil/oc/server/PacketHandler.scala index 5a54637c1..bc4e2a152 100644 --- a/src/main/scala/li/cil/oc/server/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/server/PacketHandler.scala @@ -8,6 +8,7 @@ import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.{Computer, TileEntity} import li.cil.oc.common.{PacketType, PacketHandler => CommonPacketHandler} import li.cil.oc.{Localization, Settings, api} +import net.minecraft.client.Minecraft import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP} import net.minecraft.network.NetHandlerPlayServer import net.minecraftforge.common.DimensionManager @@ -31,6 +32,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.MouseScroll => onMouseScroll(p) case PacketType.MouseUp => onMouseUp(p) case PacketType.MultiPartPlace => onMultiPartPlace(p) + case PacketType.PetVisibility => onPetVisibility(p) case PacketType.RobotAssemblerStart => onRobotAssemblerStart(p) case PacketType.RobotStateRequest => onRobotStateRequest(p) case PacketType.ServerRange => onServerRange(p) @@ -125,6 +127,22 @@ object PacketHandler extends CommonPacketHandler { } } + def onPetVisibility(p: PacketParser) { + p.player match { + case player: EntityPlayerMP if player != Minecraft.getMinecraft.thePlayer => + if (if (p.readBoolean()) { + PetVisibility.hidden.remove(player.getCommandSenderName) + } + else { + PetVisibility.hidden.add(player.getCommandSenderName) + }) { + // Something changed. + PacketSender.sendPetVisibility(Some(player.getCommandSenderName)) + } + case _ => // Invalid packet. + } + } + def onRobotAssemblerStart(p: PacketParser) = p.readTileEntity[RobotAssembler]() match { case Some(assembler) => assembler.start() diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index 941a0839c..2f903dacc 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -129,6 +129,28 @@ object PacketSender { pb.sendToNearbyPlayers(t) } + def sendPetVisibility(name: Option[String] = None, player: Option[EntityPlayerMP] = None) { + val pb = new PacketBuilder(PacketType.PetVisibility) + + name match { + case Some(n) => + pb.writeInt(1) + pb.writeUTF(n) + pb.writeBoolean(!PetVisibility.hidden.contains(n)) + case _ => + pb.writeInt(PetVisibility.hidden.size) + for (n <- PetVisibility.hidden) { + pb.writeUTF(n) + pb.writeBoolean(false) + } + } + + player match { + case Some(p) => pb.sendToPlayer(p) + case _ => pb.sendToAllPlayers() + } + } + def sendPowerState(t: PowerInformation) { val pb = new PacketBuilder(PacketType.PowerState) diff --git a/src/main/scala/li/cil/oc/server/PetVisibility.scala b/src/main/scala/li/cil/oc/server/PetVisibility.scala new file mode 100644 index 000000000..4fb68fdf2 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/PetVisibility.scala @@ -0,0 +1,7 @@ +package li.cil.oc.server + +import scala.collection.mutable + +object PetVisibility { + val hidden = mutable.Set.empty[String] +} diff --git a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala index 830b07bf9..df379898a 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -282,12 +282,17 @@ abstract class GraphicsCard extends component.ManagedComponent { else s.setBackgroundColor(0x000000) s.fill(0, 0, w, h, ' ') try { - val message = "Unrecoverable error:\n" + Localization.localizeImmediately(machine.lastError) + "\n" val wrapRegEx = s"(.{1,${math.max(1, w - 2)}})\\s".r - val lines = wrapRegEx.replaceAllIn(message, m => m.group(1) + "\n").lines.toArray + val lines = wrapRegEx.replaceAllIn(Localization.localizeImmediately(machine.lastError).replace("\t", " ") + "\n", m => m.group(1) + "\n").lines.toArray + val firstRow = ((h - lines.length) / 2) max 2 + + val message = "Unrecoverable Error" + s.set((w - message.length) / 2, firstRow - 2, message, false) + + val maxLineLength = lines.map(_.length).max + val col = ((w - maxLineLength) / 2) max 0 for ((line, idx) <- lines.zipWithIndex) { - val col = (w - line.length) / 2 - val row = (h - lines.length) / 2 + idx + val row = firstRow + idx s.set(col, row, line, false) } } diff --git a/src/main/scala/li/cil/oc/server/component/robot/Player.scala b/src/main/scala/li/cil/oc/server/component/robot/Player.scala index 90b40ef3a..953101cab 100644 --- a/src/main/scala/li/cil/oc/server/component/robot/Player.scala +++ b/src/main/scala/li/cil/oc/server/component/robot/Player.scala @@ -64,6 +64,8 @@ class Player(val robot: tileentity.Robot) extends FakePlayer(robot.world.asInsta override def getDefaultEyeHeight = 0f + override def getDisplayName = robot.name + // ----------------------------------------------------------------------- // def updatePositionAndRotation(facing: ForgeDirection, side: ForgeDirection) {