Basic integration for IGWMod, providing manual pages for blocks and items.

This commit is contained in:
Florian Nücke 2015-04-29 16:19:08 +02:00
parent 15cc9a7146
commit cb704dab33
16 changed files with 149 additions and 14 deletions

View File

@ -6,6 +6,6 @@
3D prints can be recycled by putting them as input into a [3D printer](printer.md). This will re-use some of the [chamelium](../item/chamelium.md) that was used to print them. Color that was used to print the model will not be recycled.
Holding the key for OpenComputers' extended tooltips (default is [Shift]), a print's active state will be shown, if any.
Holding the key for OpenComputers' extended tooltips (default is `Shift`), a print's active state will be shown, if any.
Printed blocks are also Forge MultiPart compatible. If present, multiple prints can be placed into a single block-space, unless they do not collide, and the total number of shapes in the block-space does not exceed the limit for a single model. Due to the nature of Forge MultiPart, prints can therefore also be placed into the same block-space as any other Forge MultiPart compatible block, such as torches, levers, cables or red alloy wires from Project Red, for example.

View File

@ -0,0 +1,5 @@
package li.cil.oc.client.renderer.markdown
object MarkupFormat extends Enumeration {
val Markdown, IGWMod = Value
}

View File

@ -1,6 +1,7 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.Document
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.gui.FontRenderer
trait BasicTextSegment extends Segment {
@ -38,6 +39,8 @@ trait BasicTextSegment extends Segment {
lines * lineHeight(renderer)
}
override def toString(format: MarkupFormat.Value): String = text
// ----------------------------------------------------------------------- //
protected def text: String

View File

@ -1,9 +1,13 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.util.EnumChatFormatting
private[markdown] class BoldSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
override protected def format = EnumChatFormatting.BOLD.toString
override def toString: String = s"{BoldSegment: text = $text}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"**$text**"
case MarkupFormat.IGWMod => s"[prefix{l}]$text [prefix{}]"
}
}

View File

@ -1,6 +1,7 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.TextBufferRenderCache
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.gui.FontRenderer
import org.lwjgl.opengl.GL11
@ -30,5 +31,8 @@ private[markdown] class CodeSegment(val parent: Segment, val text: String) exten
override protected def stringWidth(s: String, renderer: FontRenderer): Int = s.length * TextBufferRenderCache.renderer.charRenderWidth
override def toString: String = s"{CodeSegment: text = $text}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"`$text`"
case MarkupFormat.IGWMod => s"[prefix{1}]$text [prefix{}]"
}
}

View File

@ -1,5 +1,6 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.util.EnumChatFormatting
private[markdown] class HeaderSegment(parent: Segment, text: String, val level: Int) extends TextSegment(parent, text) {
@ -9,5 +10,8 @@ private[markdown] class HeaderSegment(parent: Segment, text: String, val level:
override protected def format = EnumChatFormatting.UNDERLINE.toString
override def toString: String = s"{HeaderSegment: text = $text, level = $level}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"${"#" * level} $text"
case MarkupFormat.IGWMod => s"[prefix{l}]$text [prefix{}]"
}
}

View File

@ -1,9 +1,13 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.util.EnumChatFormatting
private[markdown] class ItalicSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
override protected def format = EnumChatFormatting.ITALIC.toString
override def toString: String = s"{ItalicSegment: text = $text}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"*$text*"
case MarkupFormat.IGWMod => s"[prefix{o}]$text [prefix{}]"
}
}

View File

@ -3,8 +3,10 @@ package li.cil.oc.client.renderer.markdown.segment
import java.net.URI
import li.cil.oc.Localization
import li.cil.oc.OpenComputers
import li.cil.oc.api
import li.cil.oc.client.Manual
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.Minecraft
private[markdown] class LinkSegment(parent: Segment, text: String, val url: String) extends TextSegment(parent, text) with InteractiveSegment {
@ -54,5 +56,10 @@ private[markdown] class LinkSegment(parent: Segment, text: String, val url: Stri
}
}
override def toString: String = s"{LinkSegment: text = $text, url = $url}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"[$text]($url)"
case MarkupFormat.IGWMod =>
if (url.startsWith("http://") || url.startsWith("https://")) text
else s"[link{${OpenComputers.ID}:$url}]$text [link{}]"
}
}

View File

@ -3,6 +3,7 @@ package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.api.manual.ImageRenderer
import li.cil.oc.api.manual.InteractiveImageRenderer
import li.cil.oc.client.renderer.markdown.Document
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.gui.FontRenderer
import org.lwjgl.opengl.GL11
@ -74,5 +75,8 @@ private[markdown] class RenderSegment(val parent: Segment, val title: String, va
hovered
}
override def toString: String = s"{RendererSegment: title = $title, imageRenderer = $imageRenderer}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"![$title]($imageRenderer)"
case MarkupFormat.IGWMod => "(Sorry, images only work in the OpenComputers manual for now.)" // TODO
}
}

View File

@ -1,8 +1,10 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.client.gui.FontRenderer
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.matching.Regex
trait Segment {
@ -46,6 +48,25 @@ trait Segment {
*/
def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None
def renderAsText(format: MarkupFormat.Value): Iterable[String] = {
var segment = this
val result = mutable.Buffer.empty[String]
val builder = mutable.StringBuilder.newBuilder
while (segment != null) {
builder.append(segment.toString(format))
if (segment.isLast) {
result += builder.toString()
builder.clear()
}
segment = segment.next
}
result.toIterable
}
def toString(format: MarkupFormat.Value): String
override def toString: String = toString(MarkupFormat.Markdown)
// ----------------------------------------------------------------------- //
// Used during construction, checks a segment for inner segments.

View File

@ -1,9 +1,13 @@
package li.cil.oc.client.renderer.markdown.segment
import li.cil.oc.client.renderer.markdown.MarkupFormat
import net.minecraft.util.EnumChatFormatting
private[markdown] class StrikethroughSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
override protected def format = EnumChatFormatting.STRIKETHROUGH.toString
override def toString: String = s"{StrikethroughSegment: text = $text}"
override def toString(format: MarkupFormat.Value): String = format match {
case MarkupFormat.Markdown => s"~~$text~~"
case MarkupFormat.IGWMod => s"[prefix{m}]$text [prefix{}]"
}
}

View File

@ -96,6 +96,4 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten
case _ => None
}
}
override def toString: String = s"{TextSegment: text = $text}"
}

View File

@ -32,9 +32,9 @@ import net.minecraft.world.World
import scala.collection.mutable
object Items extends ItemAPI {
private val descriptors = mutable.Map.empty[String, ItemInfo]
val descriptors = mutable.Map.empty[String, ItemInfo]
private val names = mutable.Map.empty[Any, String]
val names = mutable.Map.empty[Any, String]
override def get(name: String): ItemInfo = descriptors.get(name).orNull

View File

@ -44,6 +44,7 @@ object Mods {
val GregTech = new ClassBasedMod(IDs.GregTech, "gregtech.api.GregTech_API")()
val IndustrialCraft2 = new SimpleMod(IDs.IndustrialCraft2, providesPower = true)
val IndustrialCraft2Classic = new SimpleMod(IDs.IndustrialCraft2Classic, providesPower = true)
val IngameWiki = new SimpleMod(IDs.IngameWiki, version = "@[1.1.3,)")
val Mekanism = new SimpleMod(IDs.Mekanism, providesPower = true)
val Minecraft = new SimpleMod(IDs.Minecraft)
val MineFactoryReloaded = new SimpleMod(IDs.MineFactoryReloaded)
@ -114,9 +115,13 @@ object Mods {
// being used rather than other more concrete implementations.
integration.computercraft.ModComputerCraft,
// We go last to ensure all other mod integration is done, e.g. to
// We go late to ensure all other mod integration is done, e.g. to
// allow properly checking if wireless redstone is present.
integration.opencomputers.ModOpenComputers
integration.opencomputers.ModOpenComputers,
// Run IGW registration after OC registration because we use the manual
// in there to know which pages to register.
integration.igw.ModIngameWiki
)
def init(): Unit = {
@ -166,6 +171,7 @@ object Mods {
final val GregTech = "gregtech"
final val IndustrialCraft2 = "IC2"
final val IndustrialCraft2Classic = "IC2-Classic"
final val IngameWiki = "IGWMod"
final val Mekanism = "Mekanism"
final val Minecraft = "Minecraft"
final val MineFactoryReloaded = "MineFactoryReloaded"

View File

@ -0,0 +1,14 @@
package li.cil.oc.integration.igw
import li.cil.oc.api.Driver
import li.cil.oc.integration.ModProxy
import li.cil.oc.integration.Mods
import net.minecraftforge.common.MinecraftForge
object ModIngameWiki extends ModProxy {
override def getMod = Mods.IngameWiki
override def initialize(): Unit = {
WikiEventHandler.init()
}
}

View File

@ -0,0 +1,57 @@
package li.cil.oc.integration.igw
import java.util
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import igwmod.api.PageChangeEvent
import igwmod.api.WikiRegistry
import li.cil.oc.OpenComputers
import li.cil.oc.api
import li.cil.oc.client.Manual
import li.cil.oc.client.renderer.markdown
import li.cil.oc.client.renderer.markdown.MarkupFormat
import li.cil.oc.common.init.Items
import net.minecraftforge.common.MinecraftForge
import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._
object WikiEventHandler {
var lastPath = ""
def init(): Unit = {
MinecraftForge.EVENT_BUS.register(this)
for ((name, info) <- Items.descriptors) {
val stack = info.createItemStack(1)
val path = api.Manual.pathFor(stack)
if (path != null && api.Manual.contentFor(path) != null) {
WikiRegistry.registerBlockAndItemPageEntry(stack)
}
}
}
@SubscribeEvent
def onPageChangeEvent(e: PageChangeEvent): Unit = {
val path =
if (e.associatedStack != null)
"/" + api.Manual.pathFor(e.associatedStack)
else if (e.currentFile.startsWith(OpenComputers.ID + ":"))
e.currentFile.stripPrefix(OpenComputers.ID + ":")
else null
val base = lastPath
lastPath = ""
if (path != null) {
val resolvedPath = Manual.makeRelative(path, base)
val content = api.Manual.contentFor(resolvedPath)
if (content != null) {
val document = markdown.Document.parse(content)
val processed = document.renderAsText(MarkupFormat.IGWMod)
e.pageText = new util.ArrayList[String](asJavaCollection(processed))
e.currentFile = resolvedPath
lastPath = resolvedPath
}
}
}
}