mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-14 09:46:53 -04:00
Added API for the ingame manual.
This commit is contained in:
parent
b0c302ff1c
commit
b28bb6b2ad
@ -4,6 +4,7 @@ import li.cil.oc.api.detail.DriverAPI;
|
|||||||
import li.cil.oc.api.detail.FileSystemAPI;
|
import li.cil.oc.api.detail.FileSystemAPI;
|
||||||
import li.cil.oc.api.detail.ItemAPI;
|
import li.cil.oc.api.detail.ItemAPI;
|
||||||
import li.cil.oc.api.detail.MachineAPI;
|
import li.cil.oc.api.detail.MachineAPI;
|
||||||
|
import li.cil.oc.api.detail.ManualAPI;
|
||||||
import li.cil.oc.api.detail.NetworkAPI;
|
import li.cil.oc.api.detail.NetworkAPI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,11 +16,12 @@ import li.cil.oc.api.detail.NetworkAPI;
|
|||||||
*/
|
*/
|
||||||
public class API {
|
public class API {
|
||||||
public static final String ID_OWNER = "OpenComputers|Core";
|
public static final String ID_OWNER = "OpenComputers|Core";
|
||||||
public static final String VERSION = "5.0.0";
|
public static final String VERSION = "5.1.0";
|
||||||
|
|
||||||
public static DriverAPI driver = null;
|
public static DriverAPI driver = null;
|
||||||
public static FileSystemAPI fileSystem = null;
|
public static FileSystemAPI fileSystem = null;
|
||||||
public static ItemAPI items = null;
|
public static ItemAPI items = null;
|
||||||
public static MachineAPI machine = null;
|
public static MachineAPI machine = null;
|
||||||
|
public static ManualAPI manual = null;
|
||||||
public static NetworkAPI network = null;
|
public static NetworkAPI network = null;
|
||||||
}
|
}
|
||||||
|
142
src/main/java/li/cil/oc/api/Manual.java
Normal file
142
src/main/java/li/cil/oc/api/Manual.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package li.cil.oc.api;
|
||||||
|
|
||||||
|
import li.cil.oc.api.manual.ContentProvider;
|
||||||
|
import li.cil.oc.api.manual.PathProvider;
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This API allows interfacing with the in-game manual of OpenComputers.
|
||||||
|
* <p/>
|
||||||
|
* It allows opening the manual at a desired specific page, as well as
|
||||||
|
* registering custom tabs and content callback handlers.
|
||||||
|
* <p/>
|
||||||
|
* Note: this is a <em>client side only</em> API. It will do nothing on
|
||||||
|
* dedicated servers (i.e. <tt>API.manual</tt> will be <tt>null</tt>).
|
||||||
|
*/
|
||||||
|
public class Manual {
|
||||||
|
/**
|
||||||
|
* Register a tab to be displayed next to the manual.
|
||||||
|
* <p/>
|
||||||
|
* These are intended to link to index pages, and for the time being there
|
||||||
|
* a relatively low number of tabs that can be displayed, so I'd ask you to
|
||||||
|
* only register as many tabs as actually, technically *needed*. Which will
|
||||||
|
* usually be one, for your main index page.
|
||||||
|
*
|
||||||
|
* @param renderer the renderer used to render the icon on your tab.
|
||||||
|
* @param path the path to the page to open when the tab is clicked.
|
||||||
|
*/
|
||||||
|
public static void addTab(TabIconRenderer renderer, String path) {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.addTab(renderer, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a path provider.
|
||||||
|
* <p/>
|
||||||
|
* Path providers are used to find documentation entries for item stacks
|
||||||
|
* and blocks in the world.
|
||||||
|
*
|
||||||
|
* @param provider the provider to register.
|
||||||
|
*/
|
||||||
|
public static void addProvider(PathProvider provider) {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.addProvider(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a content provider.
|
||||||
|
* <p/>
|
||||||
|
* Content providers are used to resolve paths to page content, if the
|
||||||
|
* standard system (using Minecraft's resource loading facilities) fails.
|
||||||
|
* <p/>
|
||||||
|
* This can be useful for providing dynamic content, for example.
|
||||||
|
*
|
||||||
|
* @param provider the provider to register.
|
||||||
|
*/
|
||||||
|
public static void addProvider(ContentProvider provider) {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.addProvider(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the documentation path for the specified item stack.
|
||||||
|
*
|
||||||
|
* @param stack the stack to find the documentation path for.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
public static String pathFor(ItemStack stack) {
|
||||||
|
if (API.manual != null)
|
||||||
|
return API.manual.pathFor(stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the documentation for the specified block in the world.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block.
|
||||||
|
* @param x the X coordinate of the block.
|
||||||
|
* @param y the Y coordinate of the block.
|
||||||
|
* @param z the Z coordinate of the block.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
public static String pathFor(World world, int x, int y, int z) {
|
||||||
|
if (API.manual != null)
|
||||||
|
return API.manual.pathFor(world, x, y, z);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of the documentation page at the specified location.
|
||||||
|
*
|
||||||
|
* @param path the path of the page to get the content of.
|
||||||
|
* @return the content of the page, or <tt>null</tt> if none exists.
|
||||||
|
*/
|
||||||
|
public static Iterable<String> contentFor(String path) {
|
||||||
|
if (API.manual != null)
|
||||||
|
return API.manual.contentFor(path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the manual for the specified player.
|
||||||
|
* <p/>
|
||||||
|
* If you wish to display a specific page, call {@link #navigate(String)}
|
||||||
|
* after this function returns, with the path to the page to show.
|
||||||
|
*
|
||||||
|
* @param player the player to open the manual for.
|
||||||
|
*/
|
||||||
|
public static void openFor(EntityPlayer player) {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.openFor(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the history of the manual.
|
||||||
|
*/
|
||||||
|
public static void reset() {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to a page in the manual.
|
||||||
|
*
|
||||||
|
* @param path the path to navigate to.
|
||||||
|
*/
|
||||||
|
public static void navigate(String path) {
|
||||||
|
if (API.manual != null)
|
||||||
|
API.manual.navigate(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
private Manual() {
|
||||||
|
}
|
||||||
|
}
|
102
src/main/java/li/cil/oc/api/detail/ManualAPI.java
Normal file
102
src/main/java/li/cil/oc/api/detail/ManualAPI.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package li.cil.oc.api.detail;
|
||||||
|
|
||||||
|
import li.cil.oc.api.manual.ContentProvider;
|
||||||
|
import li.cil.oc.api.manual.PathProvider;
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public interface ManualAPI {
|
||||||
|
/**
|
||||||
|
* Register a tab to be displayed next to the manual.
|
||||||
|
* <p/>
|
||||||
|
* These are intended to link to index pages, and for the time being there
|
||||||
|
* a relatively low number of tabs that can be displayed, so I'd ask you to
|
||||||
|
* only register as many tabs as actually, technically *needed*. Which will
|
||||||
|
* usually be one, for your main index page.
|
||||||
|
*
|
||||||
|
* @param renderer the renderer used to render the icon on your tab.
|
||||||
|
* @param path the path to the page to open when the tab is clicked.
|
||||||
|
*/
|
||||||
|
void addTab(TabIconRenderer renderer, String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a path provider.
|
||||||
|
* <p/>
|
||||||
|
* Path providers are used to find documentation entries for item stacks
|
||||||
|
* and blocks in the world.
|
||||||
|
*
|
||||||
|
* @param provider the provider to register.
|
||||||
|
*/
|
||||||
|
void addProvider(PathProvider provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a content provider.
|
||||||
|
* <p/>
|
||||||
|
* Content providers are used to resolve paths to page content, if the
|
||||||
|
* standard system (using Minecraft's resource loading facilities) fails.
|
||||||
|
* <p/>
|
||||||
|
* This can be useful for providing dynamic content, for example.
|
||||||
|
*
|
||||||
|
* @param provider the provider to register.
|
||||||
|
*/
|
||||||
|
void addProvider(ContentProvider provider);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the documentation path for the specified item stack.
|
||||||
|
*
|
||||||
|
* @param stack the stack to find the documentation path for.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
String pathFor(ItemStack stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the documentation for the specified block in the world.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block.
|
||||||
|
* @param x the X coordinate of the block.
|
||||||
|
* @param y the Y coordinate of the block.
|
||||||
|
* @param z the Z coordinate of the block.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
String pathFor(World world, int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of the documentation page at the specified location.
|
||||||
|
* <p/>
|
||||||
|
* The provided path may contain the special variable <tt>%LANGUAGE%</tt>,
|
||||||
|
* which will be resolved to the currently set language, falling back to
|
||||||
|
* <tt>en_US</tt>.
|
||||||
|
*
|
||||||
|
* @param path the path of the page to get the content of.
|
||||||
|
* @return the content of the page, or <tt>null</tt> if none exists.
|
||||||
|
*/
|
||||||
|
Iterable<String> contentFor(String path);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the manual for the specified player.
|
||||||
|
* <p/>
|
||||||
|
* If you wish to display a specific page, call {@link #navigate(String)}
|
||||||
|
* after this function returns, with the path to the page to show.
|
||||||
|
*
|
||||||
|
* @param player the player to open the manual for.
|
||||||
|
*/
|
||||||
|
void openFor(EntityPlayer player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the history of the manual.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to a page in the manual.
|
||||||
|
*
|
||||||
|
* @param path the path to navigate to.
|
||||||
|
*/
|
||||||
|
void navigate(String path);
|
||||||
|
}
|
26
src/main/java/li/cil/oc/api/manual/ContentProvider.java
Normal file
26
src/main/java/li/cil/oc/api/manual/ContentProvider.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package li.cil.oc.api.manual;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface allows implementation of content providers for the manual.
|
||||||
|
* <p/>
|
||||||
|
* Content providers can be used to provide possibly dynamic page content for
|
||||||
|
* arbitrary paths. Note that content providers have <em>lower</em> priority
|
||||||
|
* than content found in resource packs, i.e. content providers will only be
|
||||||
|
* queried for missing pages, so to speak.
|
||||||
|
*/
|
||||||
|
public interface ContentProvider {
|
||||||
|
/**
|
||||||
|
* Called to get the content of a path pointed to by the specified path.
|
||||||
|
* <p/>
|
||||||
|
* This should provide an iterable over the lines of a Markdown document
|
||||||
|
* (with the formatting provided by the in-game manual, which is a small
|
||||||
|
* subset of "normal" Markdown).
|
||||||
|
* <p/>
|
||||||
|
* If this provider cannot provide the requested path, it should return
|
||||||
|
* <tt>null</tt> to indicate so, allowing other providers to be queried.
|
||||||
|
*
|
||||||
|
* @param path the path to the manual page we're looking for.
|
||||||
|
* @return the content of the document at that path, or <tt>null</tt>.
|
||||||
|
*/
|
||||||
|
Iterable<String> getContent(String path);
|
||||||
|
}
|
45
src/main/java/li/cil/oc/api/manual/PathProvider.java
Normal file
45
src/main/java/li/cil/oc/api/manual/PathProvider.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package li.cil.oc.api.manual;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows providing paths for item stacks and blocks in the world.
|
||||||
|
* <p/>
|
||||||
|
* This is used for generating NEI usage pages with a button opening the manual
|
||||||
|
* on the page at the specified path, or for opening the manual when held in
|
||||||
|
* hand and sneak-activating a block in the world.
|
||||||
|
* <p/>
|
||||||
|
* This way you can easily make entries in your documentation available the
|
||||||
|
* same way OpenComputers does it itself.
|
||||||
|
* <p/>
|
||||||
|
* Note that you can use the special variable <tt>%LANGUAGE%</tt> in your
|
||||||
|
* paths, for language agnostic paths. These will be resolved to the currently
|
||||||
|
* set language, falling back to <tt>en_US</tt>, during actual content lookup.
|
||||||
|
*/
|
||||||
|
public interface PathProvider {
|
||||||
|
/**
|
||||||
|
* Get the path to the documentation page for the provided item stack.
|
||||||
|
* <p/>
|
||||||
|
* Return <tt>null</tt> if there is no known page for this item, allowing
|
||||||
|
* other providers to be queried.
|
||||||
|
*
|
||||||
|
* @param stack the stack to get the documentation path to.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
String pathFor(ItemStack stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path to the documentation page for the provided block.
|
||||||
|
* <p/>
|
||||||
|
* Return <tt>null</tt> if there is no known page for this item, allowing
|
||||||
|
* other providers to be queried.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block.
|
||||||
|
* @param x the X coordinate of the block.
|
||||||
|
* @param y the Y coordinate of the block.
|
||||||
|
* @param z the Z coordinate of the block.
|
||||||
|
* @return the path to the page, <tt>null</tt> if none is known.
|
||||||
|
*/
|
||||||
|
String pathFor(World world, int x, int y, int z);
|
||||||
|
}
|
22
src/main/java/li/cil/oc/api/manual/TabIconRenderer.java
Normal file
22
src/main/java/li/cil/oc/api/manual/TabIconRenderer.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package li.cil.oc.api.manual;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows defining a renderer for a manual tab.
|
||||||
|
* <p/>
|
||||||
|
* Each renderer instance represents the single graphic it is drawing. To
|
||||||
|
* provide different graphics for different tabs you'll need to create
|
||||||
|
* multiple tab renderer instances.
|
||||||
|
* <p/>
|
||||||
|
* See the prefabs {@link li.cil.oc.api.prefab.ItemStackTabIconRenderer} and
|
||||||
|
* {@link li.cil.oc.api.prefab.IconTabIconRenderer} for simple standard
|
||||||
|
* implementations.
|
||||||
|
*/
|
||||||
|
public interface TabIconRenderer {
|
||||||
|
/**
|
||||||
|
* Called when icon of a tab should be rendered.
|
||||||
|
* <p/>
|
||||||
|
* This should render something in a 16x16 area. The OpenGL state has been
|
||||||
|
* adjusted so that drawing starts at (0,0,0), and should go to (16,16,0).
|
||||||
|
*/
|
||||||
|
void render();
|
||||||
|
}
|
14
src/main/java/li/cil/oc/api/manual/package-info.java
Normal file
14
src/main/java/li/cil/oc/api/manual/package-info.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* This package contains manual related interfaces.
|
||||||
|
* <p/>
|
||||||
|
* The manual represents the in-game documentation of OpenComputers and any
|
||||||
|
* other mod that may choose to add its documentation to it, such as addon
|
||||||
|
* mods.
|
||||||
|
*/
|
||||||
|
@cpw.mods.fml.common.API(
|
||||||
|
owner = API.ID_OWNER,
|
||||||
|
provides = "OpenComputersAPI|Manual",
|
||||||
|
apiVersion = API.VERSION)
|
||||||
|
package li.cil.oc.api.manual;
|
||||||
|
|
||||||
|
import li.cil.oc.api.API;
|
28
src/main/java/li/cil/oc/api/prefab/IconTabIconRenderer.java
Normal file
28
src/main/java/li/cil/oc/api/prefab/IconTabIconRenderer.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package li.cil.oc.api.prefab;
|
||||||
|
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.util.IIcon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of a tab icon renderer using an icon as its graphic.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
|
public class IconTabIconRenderer implements TabIconRenderer {
|
||||||
|
private final IIcon icon;
|
||||||
|
|
||||||
|
public IconTabIconRenderer(IIcon icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
final Tessellator t = Tessellator.instance;
|
||||||
|
t.startDrawingQuads();
|
||||||
|
t.addVertexWithUV(0, 16, 0, icon.getMinU(), icon.getMaxV());
|
||||||
|
t.addVertexWithUV(16, 16, 0, icon.getMaxU(), icon.getMaxV());
|
||||||
|
t.addVertexWithUV(16, 0, 0, icon.getMaxU(), icon.getMinV());
|
||||||
|
t.addVertexWithUV(0, 0, 0, icon.getMinU(), icon.getMinV());
|
||||||
|
t.draw();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package li.cil.oc.api.prefab;
|
||||||
|
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.OpenGlHelper;
|
||||||
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of a tab icon renderer using an item stack as its graphic.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
|
public class ItemStackTabIconRenderer implements TabIconRenderer {
|
||||||
|
private final ItemStack stack;
|
||||||
|
|
||||||
|
public ItemStackTabIconRenderer(ItemStack stack) {
|
||||||
|
this.stack = stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||||
|
RenderHelper.enableGUIStandardItemLighting();
|
||||||
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
||||||
|
RenderItem.getInstance().renderItemAndEffectIntoGUI(Minecraft.getMinecraft().fontRenderer, Minecraft.getMinecraft().getTextureManager(), stack, 0, 0);
|
||||||
|
RenderHelper.disableStandardItemLighting();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package li.cil.oc.api.prefab;
|
||||||
|
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of a tab icon renderer using a full texture as its graphic.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
|
public class TextureTabIconRenderer implements TabIconRenderer {
|
||||||
|
private final ResourceLocation location;
|
||||||
|
|
||||||
|
public TextureTabIconRenderer(ResourceLocation location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
Minecraft.getMinecraft().getTextureManager().bindTexture(location);
|
||||||
|
final Tessellator t = Tessellator.instance;
|
||||||
|
t.startDrawingQuads();
|
||||||
|
t.addVertexWithUV(0, 16, 0, 0, 1);
|
||||||
|
t.addVertexWithUV(16, 16, 0, 1, 1);
|
||||||
|
t.addVertexWithUV(16, 0, 0, 1, 0);
|
||||||
|
t.addVertexWithUV(0, 0, 0, 0, 0);
|
||||||
|
t.draw();
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 216 B |
131
src/main/scala/li/cil/oc/client/Manual.scala
Normal file
131
src/main/scala/li/cil/oc/client/Manual.scala
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package li.cil.oc.client
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.FMLCommonHandler
|
||||||
|
import li.cil.oc.OpenComputers
|
||||||
|
import li.cil.oc.api.detail.ManualAPI
|
||||||
|
import li.cil.oc.api.manual.ContentProvider
|
||||||
|
import li.cil.oc.api.manual.PathProvider
|
||||||
|
import li.cil.oc.api.manual.TabIconRenderer
|
||||||
|
import li.cil.oc.common.GuiType
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
import scala.annotation.tailrec
|
||||||
|
import scala.collection.convert.WrapAsJava._
|
||||||
|
import scala.collection.convert.WrapAsScala._
|
||||||
|
import scala.collection.mutable
|
||||||
|
|
||||||
|
object Manual extends ManualAPI {
|
||||||
|
final val LanguageKey = "%LANGUAGE%"
|
||||||
|
|
||||||
|
final val FallbackLanguage = "en_US"
|
||||||
|
|
||||||
|
class History(val path: String, var offset: Int = 0)
|
||||||
|
|
||||||
|
class Tab(val renderer: TabIconRenderer, val path: String)
|
||||||
|
|
||||||
|
val tabs = mutable.Buffer.empty[Tab]
|
||||||
|
|
||||||
|
val pathProviders = mutable.Buffer.empty[PathProvider]
|
||||||
|
|
||||||
|
val contentProviders = mutable.Buffer.empty[ContentProvider]
|
||||||
|
|
||||||
|
val history = new mutable.Stack[History]
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
|
override def addTab(renderer: TabIconRenderer, path: String): Unit = {
|
||||||
|
tabs += new Tab(renderer, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def addProvider(provider: PathProvider): Unit = {
|
||||||
|
pathProviders += provider
|
||||||
|
}
|
||||||
|
|
||||||
|
override def addProvider(provider: ContentProvider): Unit = {
|
||||||
|
contentProviders += provider
|
||||||
|
}
|
||||||
|
|
||||||
|
override def pathFor(stack: ItemStack): String = {
|
||||||
|
for (provider <- pathProviders) {
|
||||||
|
val path = try provider.pathFor(stack) catch {
|
||||||
|
case t: Throwable =>
|
||||||
|
OpenComputers.log.warn("A path provider threw an error when queried with an item.", t)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (path != null) return path
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def pathFor(world: World, x: Int, y: Int, z: Int): String = {
|
||||||
|
for (provider <- pathProviders) {
|
||||||
|
val path = try provider.pathFor(world, x, y, z) catch {
|
||||||
|
case t: Throwable =>
|
||||||
|
OpenComputers.log.warn("A path provider threw an error when queried with a block.", t)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (path != null) return path
|
||||||
|
}
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def contentFor(path: String): java.lang.Iterable[String] = {
|
||||||
|
val language = FMLCommonHandler.instance.getCurrentLanguage
|
||||||
|
contentForWithRedirects(path.replaceAll(LanguageKey, language)).
|
||||||
|
orElse(contentForWithRedirects(path.replaceAll(LanguageKey, FallbackLanguage))).
|
||||||
|
getOrElse(asJavaIterable(Iterable("Document not found: " + path)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def openFor(player: EntityPlayer): Unit = {
|
||||||
|
if (player.getEntityWorld.isRemote) {
|
||||||
|
player.openGui(OpenComputers, GuiType.Manual.id, player.getEntityWorld, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def reset(): Unit = {
|
||||||
|
history.clear()
|
||||||
|
history.push(new History(s"doc/$LanguageKey/index.md"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override def navigate(path: String): Unit = {
|
||||||
|
Minecraft.getMinecraft.currentScreen match {
|
||||||
|
case manual: gui.Manual => manual.pushPage(path)
|
||||||
|
case _ => history.push(new History(path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def makeRelative(path: String, base: String): String =
|
||||||
|
if (path.startsWith("/")) path
|
||||||
|
else {
|
||||||
|
val splitAt = base.lastIndexOf('/')
|
||||||
|
if (splitAt >= 0) base.splitAt(splitAt)._1 + "/" + path
|
||||||
|
else path
|
||||||
|
}
|
||||||
|
|
||||||
|
@tailrec private def contentForWithRedirects(path: String, seen: List[String] = List.empty): Option[java.lang.Iterable[String]] = {
|
||||||
|
if (seen.contains(path)) return Some(asJavaIterable(Iterable("Redirection loop: ") ++ seen ++ Iterable(path)))
|
||||||
|
doContentLookup(path) match {
|
||||||
|
case Some(content) => content.headOption match {
|
||||||
|
case Some(line) if line.toLowerCase.startsWith("#redirect ") =>
|
||||||
|
contentForWithRedirects(makeRelative(line.substring("#redirect ".length), path), seen :+ path)
|
||||||
|
case _ => Some(content)
|
||||||
|
}
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private def doContentLookup(path: String): Option[java.lang.Iterable[String]] = {
|
||||||
|
for (provider <- contentProviders) {
|
||||||
|
val lines = try provider.getContent(path) catch {
|
||||||
|
case t: Throwable =>
|
||||||
|
OpenComputers.log.warn("A content provider threw an error when queried.", t)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
if (lines != null) return Some(lines)
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import cpw.mods.fml.common.network.NetworkRegistry
|
|||||||
import li.cil.oc.Constants
|
import li.cil.oc.Constants
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
|
import li.cil.oc.api
|
||||||
import li.cil.oc.client
|
import li.cil.oc.client
|
||||||
import li.cil.oc.client.renderer.HighlightRenderer
|
import li.cil.oc.client.renderer.HighlightRenderer
|
||||||
import li.cil.oc.client.renderer.PetRenderer
|
import li.cil.oc.client.renderer.PetRenderer
|
||||||
@ -33,6 +34,8 @@ private[oc] class Proxy extends CommonProxy {
|
|||||||
override def preInit(e: FMLPreInitializationEvent) {
|
override def preInit(e: FMLPreInitializationEvent) {
|
||||||
super.preInit(e)
|
super.preInit(e)
|
||||||
|
|
||||||
|
api.API.manual = client.Manual
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.register(Sound)
|
MinecraftForge.EVENT_BUS.register(Sound)
|
||||||
MinecraftForge.EVENT_BUS.register(gui.Icons)
|
MinecraftForge.EVENT_BUS.register(gui.Icons)
|
||||||
MinecraftForge.EVENT_BUS.register(HighlightRenderer)
|
MinecraftForge.EVENT_BUS.register(HighlightRenderer)
|
||||||
|
@ -26,6 +26,7 @@ object Textures {
|
|||||||
val guiDrone = new ResourceLocation(Settings.resourceDomain, "textures/gui/drone.png")
|
val guiDrone = new ResourceLocation(Settings.resourceDomain, "textures/gui/drone.png")
|
||||||
val guiKeyboardMissing = new ResourceLocation(Settings.resourceDomain, "textures/gui/keyboard_missing.png")
|
val guiKeyboardMissing = new ResourceLocation(Settings.resourceDomain, "textures/gui/keyboard_missing.png")
|
||||||
val guiManual = new ResourceLocation(Settings.resourceDomain, "textures/gui/manual.png")
|
val guiManual = new ResourceLocation(Settings.resourceDomain, "textures/gui/manual.png")
|
||||||
|
val guiManualTab = new ResourceLocation(Settings.resourceDomain, "textures/gui/manual_tab.png")
|
||||||
val guiPrinter = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer.png")
|
val guiPrinter = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer.png")
|
||||||
val guiPrinterInk = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_ink.png")
|
val guiPrinterInk = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_ink.png")
|
||||||
val guiPrinterMaterial = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_material.png")
|
val guiPrinterMaterial = new ResourceLocation(Settings.resourceDomain, "textures/gui/printer_material.png")
|
||||||
|
@ -1,44 +1,23 @@
|
|||||||
package li.cil.oc.client.gui
|
package li.cil.oc.client.gui
|
||||||
|
|
||||||
import java.io.FileNotFoundException
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util
|
import java.util
|
||||||
|
|
||||||
import com.google.common.base.Charsets
|
|
||||||
import cpw.mods.fml.common.FMLCommonHandler
|
|
||||||
import li.cil.oc.Localization
|
import li.cil.oc.Localization
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.client.Manual
|
||||||
import li.cil.oc.client.Textures
|
import li.cil.oc.client.Textures
|
||||||
import li.cil.oc.util.PseudoMarkdown
|
import li.cil.oc.util.PseudoMarkdown
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.Gui
|
import net.minecraft.client.gui.Gui
|
||||||
|
import net.minecraft.client.gui.GuiButton
|
||||||
import net.minecraft.client.gui.GuiScreen
|
import net.minecraft.client.gui.GuiScreen
|
||||||
import net.minecraft.client.gui.ScaledResolution
|
import net.minecraft.client.gui.ScaledResolution
|
||||||
import net.minecraft.util.ResourceLocation
|
|
||||||
import org.lwjgl.input.Mouse
|
import org.lwjgl.input.Mouse
|
||||||
|
import org.lwjgl.opengl.GL11
|
||||||
|
|
||||||
import scala.collection.convert.WrapAsJava._
|
import scala.collection.convert.WrapAsJava._
|
||||||
import scala.collection.mutable
|
import scala.collection.convert.WrapAsScala._
|
||||||
import scala.io.Source
|
|
||||||
|
|
||||||
object Manual {
|
|
||||||
final val LanguageKey = "%LANGUAGE%"
|
|
||||||
|
|
||||||
val history = new mutable.Stack[History]
|
|
||||||
|
|
||||||
reset()
|
|
||||||
|
|
||||||
def reset(): Unit = {
|
|
||||||
history.clear()
|
|
||||||
history.push(new History(s"doc/$LanguageKey/index.md"))
|
|
||||||
}
|
|
||||||
|
|
||||||
class History(val path: String) {
|
|
||||||
var offset = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Manual extends GuiScreen {
|
class Manual extends GuiScreen {
|
||||||
final val documentMaxWidth = 230
|
final val documentMaxWidth = 230
|
||||||
@ -47,6 +26,10 @@ class Manual extends GuiScreen {
|
|||||||
final val scrollPosY = 6
|
final val scrollPosY = 6
|
||||||
final val scrollWidth = 6
|
final val scrollWidth = 6
|
||||||
final val scrollHeight = 180
|
final val scrollHeight = 180
|
||||||
|
final val tabPosX = -23
|
||||||
|
final val tabPosY = 7
|
||||||
|
final val tabWidth = 23
|
||||||
|
final val tabHeight = 26
|
||||||
|
|
||||||
var guiLeft = 0
|
var guiLeft = 0
|
||||||
var guiTop = 0
|
var guiTop = 0
|
||||||
@ -74,37 +57,8 @@ class Manual extends GuiScreen {
|
|||||||
else path
|
else path
|
||||||
}
|
}
|
||||||
|
|
||||||
def loadPage(path: String, localized: Boolean = false, seen: List[String] = List.empty): Iterator[String] = {
|
|
||||||
val language = FMLCommonHandler.instance.getCurrentLanguage
|
|
||||||
val resolvedPath = path.replaceAll(Manual.LanguageKey, language)
|
|
||||||
if (seen.contains(resolvedPath)) return Iterator("Redirection loop: ") ++ seen.iterator ++ Iterator(path)
|
|
||||||
val location = new ResourceLocation(Settings.resourceDomain, resolvedPath)
|
|
||||||
var is: InputStream = null
|
|
||||||
try {
|
|
||||||
val resource = Minecraft.getMinecraft.getResourceManager.getResource(location)
|
|
||||||
is = resource.getInputStream
|
|
||||||
// Force resolving immediately via toArray, otherwise we return a read
|
|
||||||
// iterator on a closed input stream (because of the finally).
|
|
||||||
val lines = Source.fromInputStream(is)(Charsets.UTF_8).getLines().toArray
|
|
||||||
lines.headOption match {
|
|
||||||
case Some(line) if line.toLowerCase.startsWith("#redirect ") =>
|
|
||||||
loadPage(resolveLink(line.substring("#redirect ".length), resolvedPath), localized = false, seen :+ path)
|
|
||||||
case _ => lines.iterator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
case e: FileNotFoundException if !localized && language != "en_US" =>
|
|
||||||
loadPage(path.replaceAll(Manual.LanguageKey, "en_US"), localized = true, seen)
|
|
||||||
case t: Throwable =>
|
|
||||||
Iterator(s"Failed loading page '$path':") ++ t.toString.lines
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Option(is).foreach(_.close())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def refreshPage(): Unit = {
|
def refreshPage(): Unit = {
|
||||||
document = PseudoMarkdown.parse(loadPage(Manual.history.top.path))
|
document = PseudoMarkdown.parse(api.Manual.contentFor(Manual.history.top.path))
|
||||||
documentHeight = PseudoMarkdown.height(document, documentMaxWidth, fontRendererObj)
|
documentHeight = PseudoMarkdown.height(document, documentMaxWidth, fontRendererObj)
|
||||||
scrollTo(offset)
|
scrollTo(offset)
|
||||||
}
|
}
|
||||||
@ -129,6 +83,12 @@ class Manual extends GuiScreen {
|
|||||||
|
|
||||||
override def doesGuiPauseGame = false
|
override def doesGuiPauseGame = false
|
||||||
|
|
||||||
|
override def actionPerformed(button: GuiButton): Unit = {
|
||||||
|
if (button.id >= 0 && button.id < Manual.tabs.length) {
|
||||||
|
pushPage(Manual.tabs(button.id).path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override def initGui(): Unit = {
|
override def initGui(): Unit = {
|
||||||
super.initGui()
|
super.initGui()
|
||||||
|
|
||||||
@ -141,9 +101,15 @@ class Manual extends GuiScreen {
|
|||||||
xSize = guiSize.getScaledWidth
|
xSize = guiSize.getScaledWidth
|
||||||
ySize = guiSize.getScaledHeight
|
ySize = guiSize.getScaledHeight
|
||||||
|
|
||||||
scrollButton = new ImageButton(1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.guiButtonScroll)
|
scrollButton = new ImageButton(-1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.guiButtonScroll)
|
||||||
add(buttonList, scrollButton)
|
add(buttonList, scrollButton)
|
||||||
|
|
||||||
|
for ((tab, i) <- Manual.tabs.zipWithIndex if i < 7) {
|
||||||
|
val x = guiLeft + tabPosX
|
||||||
|
val y = guiTop + tabPosY + i * (tabHeight - 1)
|
||||||
|
add(buttonList, new ImageButton(0, x, y, tabWidth, tabHeight, Textures.guiManualTab))
|
||||||
|
}
|
||||||
|
|
||||||
refreshPage()
|
refreshPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +122,15 @@ class Manual extends GuiScreen {
|
|||||||
|
|
||||||
super.drawScreen(mouseX, mouseY, dt)
|
super.drawScreen(mouseX, mouseY, dt)
|
||||||
|
|
||||||
|
for ((tab, i) <- Manual.tabs.zipWithIndex if i < 7) {
|
||||||
|
val x = guiLeft + tabPosX
|
||||||
|
val y = guiTop + tabPosY + i * (tabHeight - 1)
|
||||||
|
GL11.glPushMatrix()
|
||||||
|
GL11.glTranslated(x + 5, y + 5, zLevel)
|
||||||
|
tab.renderer.render()
|
||||||
|
GL11.glPopMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
PseudoMarkdown.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRendererObj, mouseX, mouseY) match {
|
PseudoMarkdown.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRendererObj, mouseX, mouseY) match {
|
||||||
case Some(segment) =>
|
case Some(segment) =>
|
||||||
segment.tooltip match {
|
segment.tooltip match {
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
package li.cil.oc.common.item
|
package li.cil.oc.common.item
|
||||||
|
|
||||||
import li.cil.oc.OpenComputers
|
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
import li.cil.oc.client.gui
|
|
||||||
import li.cil.oc.common.GuiType
|
|
||||||
import li.cil.oc.common.block.SimpleBlock
|
|
||||||
import li.cil.oc.util.BlockPosition
|
import li.cil.oc.util.BlockPosition
|
||||||
import li.cil.oc.util.ExtendedWorld._
|
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
@ -16,26 +10,21 @@ class Manual(val parent: Delegator) extends Delegate {
|
|||||||
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = {
|
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = {
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
if (player.isSneaking) {
|
if (player.isSneaking) {
|
||||||
gui.Manual.reset()
|
api.Manual.reset()
|
||||||
}
|
}
|
||||||
player.openGui(OpenComputers, GuiType.Manual.id, world, 0, 0, 0)
|
api.Manual.openFor(player)
|
||||||
}
|
}
|
||||||
super.onItemRightClick(stack, world, player)
|
super.onItemRightClick(stack, world, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: Int, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||||
val world = player.getEntityWorld
|
val world = player.getEntityWorld
|
||||||
world.getBlock(position) match {
|
api.Manual.pathFor(world, position.x, position.y, position.z) match {
|
||||||
case block: SimpleBlock =>
|
case path: String =>
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
player.openGui(OpenComputers, GuiType.Manual.id, world, 0, 0, 0)
|
api.Manual.openFor(player)
|
||||||
Minecraft.getMinecraft.currentScreen match {
|
api.Manual.reset()
|
||||||
case manual: gui.Manual =>
|
api.Manual.navigate(path)
|
||||||
gui.Manual.reset()
|
|
||||||
val descriptor = api.Items.get(new ItemStack(block))
|
|
||||||
manual.pushPage("block/" + descriptor.name + ".md")
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
case _ => super.onItemUse(stack, player, position, side, hitX, hitY, hitZ)
|
case _ => super.onItemUse(stack, player, position, side, hitX, hitY, hitZ)
|
||||||
|
@ -8,10 +8,7 @@ import codechicken.nei.api.IOverlayHandler
|
|||||||
import codechicken.nei.api.IRecipeOverlayRenderer
|
import codechicken.nei.api.IRecipeOverlayRenderer
|
||||||
import codechicken.nei.recipe.GuiRecipe
|
import codechicken.nei.recipe.GuiRecipe
|
||||||
import codechicken.nei.recipe.IUsageHandler
|
import codechicken.nei.recipe.IUsageHandler
|
||||||
import li.cil.oc.OpenComputers
|
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
import li.cil.oc.client.gui
|
|
||||||
import li.cil.oc.common.GuiType
|
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.GuiButton
|
import net.minecraft.client.gui.GuiButton
|
||||||
import net.minecraft.client.gui.inventory.GuiContainer
|
import net.minecraft.client.gui.inventory.GuiContainer
|
||||||
@ -30,9 +27,8 @@ class ManualUsageHandler(path: Option[String]) extends IUsageHandler {
|
|||||||
override def getUsageHandler(input: String, ingredients: AnyRef*): IUsageHandler = {
|
override def getUsageHandler(input: String, ingredients: AnyRef*): IUsageHandler = {
|
||||||
if (input == "item") {
|
if (input == "item") {
|
||||||
ingredients.collectFirst {
|
ingredients.collectFirst {
|
||||||
case stack: ItemStack if api.Items.get(stack) != null =>
|
case stack: ItemStack if api.Manual.pathFor(stack) != null =>
|
||||||
val descriptor = api.Items.get(stack)
|
new ManualUsageHandler(Option(api.Manual.pathFor(stack)))
|
||||||
new ManualUsageHandler(Option((if (descriptor.block != null) "block/" else "item/") + descriptor.name + ".md"))
|
|
||||||
}.getOrElse(this)
|
}.getOrElse(this)
|
||||||
}
|
}
|
||||||
else this
|
else this
|
||||||
@ -76,11 +72,8 @@ class ManualUsageHandler(path: Option[String]) extends IUsageHandler {
|
|||||||
val pos = GuiDraw.getMousePosition
|
val pos = GuiDraw.getMousePosition
|
||||||
val mc = Minecraft.getMinecraft
|
val mc = Minecraft.getMinecraft
|
||||||
if (button.mousePressed(mc, pos.x - container.guiLeft - 5, pos.y - container.guiTop - 16)) {
|
if (button.mousePressed(mc, pos.x - container.guiLeft - 5, pos.y - container.guiTop - 16)) {
|
||||||
mc.thePlayer.openGui(OpenComputers, GuiType.Manual.id, mc.theWorld, 0, 0, 0)
|
api.Manual.openFor(mc.thePlayer)
|
||||||
mc.currentScreen match {
|
path.foreach(api.Manual.navigate)
|
||||||
case manual: gui.Manual => path.foreach(manual.pushPage)
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else false
|
else false
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
package li.cil.oc.integration.opencomputers
|
package li.cil.oc.integration.opencomputers
|
||||||
|
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.lang.Iterable
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets
|
||||||
import cpw.mods.fml.common.FMLCommonHandler
|
import cpw.mods.fml.common.FMLCommonHandler
|
||||||
import cpw.mods.fml.common.event.FMLInterModComms
|
import cpw.mods.fml.common.event.FMLInterModComms
|
||||||
import li.cil.oc.Constants
|
import li.cil.oc.Constants
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
|
import li.cil.oc.api.detail.ItemInfo
|
||||||
import li.cil.oc.api.internal
|
import li.cil.oc.api.internal
|
||||||
|
import li.cil.oc.api.manual.ContentProvider
|
||||||
|
import li.cil.oc.api.manual.PathProvider
|
||||||
import li.cil.oc.common.EventHandler
|
import li.cil.oc.common.EventHandler
|
||||||
import li.cil.oc.common.Loot
|
import li.cil.oc.common.Loot
|
||||||
import li.cil.oc.common.SaveHandler
|
import li.cil.oc.common.SaveHandler
|
||||||
import li.cil.oc.common.asm.SimpleComponentTickHandler
|
import li.cil.oc.common.asm.SimpleComponentTickHandler
|
||||||
|
import li.cil.oc.common.block.SimpleBlock
|
||||||
import li.cil.oc.common.event._
|
import li.cil.oc.common.event._
|
||||||
import li.cil.oc.common.item.Analyzer
|
import li.cil.oc.common.item.Analyzer
|
||||||
import li.cil.oc.common.item.Delegator
|
import li.cil.oc.common.item.Delegator
|
||||||
@ -22,10 +31,17 @@ import li.cil.oc.integration.util.BundledRedstone
|
|||||||
import li.cil.oc.integration.util.WirelessRedstone
|
import li.cil.oc.integration.util.WirelessRedstone
|
||||||
import li.cil.oc.server.network.WirelessNetwork
|
import li.cil.oc.server.network.WirelessNetwork
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import net.minecraft.world.World
|
||||||
import net.minecraftforge.common.ForgeChunkManager
|
import net.minecraftforge.common.ForgeChunkManager
|
||||||
import net.minecraftforge.common.MinecraftForge
|
import net.minecraftforge.common.MinecraftForge
|
||||||
|
|
||||||
|
import scala.collection.convert.WrapAsJava._
|
||||||
|
import scala.io.Source
|
||||||
|
|
||||||
object ModOpenComputers extends ModProxy {
|
object ModOpenComputers extends ModProxy {
|
||||||
override def getMod = Mods.OpenComputers
|
override def getMod = Mods.OpenComputers
|
||||||
|
|
||||||
@ -188,6 +204,9 @@ object ModOpenComputers extends ModProxy {
|
|||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.Manual.addProvider(DefinitionPathProvider)
|
||||||
|
api.Manual.addProvider(ResourceContentProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
private def blacklistHost(host: Class[_], itemNames: String*) {
|
private def blacklistHost(host: Class[_], itemNames: String*) {
|
||||||
@ -199,4 +218,46 @@ object ModOpenComputers extends ModProxy {
|
|||||||
FMLInterModComms.sendMessage("OpenComputers", "blacklistHost", nbt)
|
FMLInterModComms.sendMessage("OpenComputers", "blacklistHost", nbt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object DefinitionPathProvider extends PathProvider {
|
||||||
|
private final val Blacklist = Set(
|
||||||
|
"debugger"
|
||||||
|
)
|
||||||
|
|
||||||
|
override def pathFor(stack: ItemStack): String = Option(api.Items.get(stack)) match {
|
||||||
|
case Some(definition) => checkBlacklisted(definition)
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def pathFor(world: World, x: Int, y: Int, z: Int): String = world.getBlock(x, y, z) match {
|
||||||
|
case block: SimpleBlock => checkBlacklisted(api.Items.get(new ItemStack(block)))
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
|
||||||
|
private def checkBlacklisted(info: ItemInfo): String =
|
||||||
|
if (info == null || Blacklist.contains(info.name)) null
|
||||||
|
else if (info.block != null) "block/" + info.name + ".md"
|
||||||
|
else "item/" + info.name + ".md"
|
||||||
|
}
|
||||||
|
|
||||||
|
object ResourceContentProvider extends ContentProvider {
|
||||||
|
override def getContent(path: String): Iterable[String] = {
|
||||||
|
val location = new ResourceLocation(Settings.resourceDomain, path)
|
||||||
|
var is: InputStream = null
|
||||||
|
try {
|
||||||
|
val resource = Minecraft.getMinecraft.getResourceManager.getResource(location)
|
||||||
|
is = resource.getInputStream
|
||||||
|
// Force resolving immediately via toArray, otherwise we return a read
|
||||||
|
// iterator on a closed input stream (because of the finally).
|
||||||
|
asJavaIterable(Source.fromInputStream(is)(Charsets.UTF_8).getLines().toArray.toIterable)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
case t: Throwable => null
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Option(is).foreach(_.close())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ object PseudoMarkdown {
|
|||||||
/**
|
/**
|
||||||
* Parses a plain text document into a list of segments.
|
* Parses a plain text document into a list of segments.
|
||||||
*/
|
*/
|
||||||
def parse(document: Iterator[String]): Iterable[Segment] = {
|
def parse(document: Iterable[String]): Iterable[Segment] = {
|
||||||
var segments = document.flatMap(line => Iterable(new TextSegment(null, Option(line).getOrElse("")), new NewLineSegment())).toArray
|
var segments = document.flatMap(line => Iterable(new TextSegment(null, Option(line).getOrElse("")), new NewLineSegment())).toArray
|
||||||
for ((pattern, factory) <- segmentTypes) {
|
for ((pattern, factory) <- segmentTypes) {
|
||||||
segments = segments.flatMap(_.refine(pattern, factory))
|
segments = segments.flatMap(_.refine(pattern, factory))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user