Include CraftGuide API in project, excluded from JAR

It rarely updates, and the gradle git thing was never working for me
This commit is contained in:
mezz committed 2015-06-20 16:14:59 -07:00
1 parent 3488a39016
commit edd7dd098b
26 files changed
+1707 -31

No files matched your search

+5 -31
View File
@@ -35,9 +35,6 @@ ext.dirLang = "./lang"
ext.apiForestry = "./api/forestry"
ext.apiRedstoneFlux = "./api/redstoneflux"
ext.CraftGuideRepo = "https://github.com/Uristqwerty/CraftGuide.git"
ext.CraftGuideTmp = "build/tmp/CraftGuide"
minecraft {
version = mcversion + "-" + forgeversion
runDir = "run"
@@ -47,13 +44,6 @@ minecraft {
}
sourceSets {
api {
java {
srcDir CraftGuideTmp + "/src"
include '**/CraftGuide/api/**'
}
}
main {
java {
srcDir project.apiForestry
@@ -160,23 +150,6 @@ task bumpPatch << {
saveVersion()
}
import org.ajoberstar.grgit.Grgit
task initCraftGuide << {
def localRepo = file(CraftGuideTmp)
if (localRepo.exists()) {
println 'Updating CraftGuide repo'
def grgit = Grgit.open(localRepo)
grgit.pull()
grgit.close()
} else {
println 'Cloning CraftGuide repo'
def grgit = Grgit.clone(dir: localRepo, uri: CraftGuideRepo)
grgit.close()
}
}
jar {
destinationDir = file("build/tmp")
archiveName = "main.jar"
@@ -197,6 +170,7 @@ task mainJarSigned ( type: Jar, dependsOn: 'reobf' ) {
from (zipTree(jar.getArchivePath())) {
exclude '**/api/**'
exclude '**/codechicken/**'
exclude '**/uristqwerty/**'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -223,6 +197,7 @@ task mainJar ( type: Zip, dependsOn: mainJarSigned ) {
from (zipTree(jar.getArchivePath())) {
include '**'
exclude '**/codechicken/**'
exclude '**/uristqwerty/**'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -235,6 +210,7 @@ task devJarSigned ( type: Jar, dependsOn: 'classes' ) {
from(sourceSets.main.output) {
exclude '**/api/**'
exclude '**/codechicken/**'
exclude '**/uristqwerty/**'
}
destinationDir = file("build/tmp")
@@ -260,11 +236,13 @@ task devJar ( type: Zip, dependsOn: devJarSigned ) {
from(sourceSets.main.allSource) {
include '**'
exclude '**/codechicken/**'
exclude '**/uristqwerty/**'
}
from(sourceSets.main.output) {
include '**'
exclude '**/codechicken/**'
exclude '**/uristqwerty/**'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -299,10 +277,6 @@ mainJar.shouldRunAfter releaseInit
devJar.shouldRunAfter releaseInit
apiJar.shouldRunAfter releaseInit
afterEvaluate {
compileApiJava.dependsOn initCraftGuide
}
artifacts {
archives apiJar
archives devJar
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Uristqwerty
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,21 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
/**
* Supports a simple filter, allowing recipes to be removed
* if they match certain conditions.
*/
public interface BasicRecipeFilter
{
/**
* When CraftGuide loads or reloads its recipe list, this
* method will be called for every recipe. If this method
* returns false for a recipe, that recipe will be removed.
*
* @param recipe
* @param recipeType
* @return
*/
public boolean shouldKeepRecipe(CraftGuideRecipe recipe, ItemStack recipeType);
}
@@ -0,0 +1,82 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
* An ItemSlot that appends probability information to the name of
* the item it contains. To use it, instead of putting an ItemStack
* or List in the data array, put an Object[] containing the item
* at index 0, and an Integer representing the probability at index
* 1.
*
* Also worth noting, this class does not require any additional support
* within the rest of CraftGuide. If you copy it into a different package,
* and use that copy, it will function just fine with older versions of
* CraftGuide, as well as newer ones. It also shows how the API is set up
* to make that sort of extension possible.
*/
public class ChanceSlot extends ItemSlot
{
private int ratio = 100;
private String formatString = " (%1$.0f%% chance)";
public ChanceSlot(int x, int y, int width, int height)
{
super(x, y, width, height);
}
public ChanceSlot(int x, int y, int width, int height, boolean drawQuantity)
{
super(x, y, width, height, drawQuantity);
}
@Override
public void draw(Renderer renderer, int x, int y, Object[] data, int dataIndex, boolean isMouseOver)
{
implementation.draw(this, renderer, x, y, stack(data, dataIndex), isMouseOver);
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
if(data[dataIndex] == null || stack(data, dataIndex) == null)
{
return implementation.getTooltip(this, null);
}
List<String> tooltip = implementation.getTooltip(this, stack(data, dataIndex));
double probability = ((Integer)((Object[])data[dataIndex])[1]) * 100 / (double)ratio;
tooltip.set(0, tooltip.get(0) + String.format(formatString, probability));
return tooltip;
}
@Override
public boolean matches(ItemFilter search, Object[] data, int dataIndex, SlotType type)
{
return implementation.matches(this, search, stack(data, dataIndex), type);
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
return implementation.getClickedFilter(x, y, stack(data, dataIndex));
}
private Object stack(Object[] data, int dataIndex)
{
return data[dataIndex] != null? ((Object[])data[dataIndex])[0] : null;
}
public ChanceSlot setRatio(int ratio)
{
this.ratio = ratio;
return this;
}
public ChanceSlot setFormatString(String format)
{
formatString = format;
return this;
}
}
@@ -0,0 +1,52 @@
package uristqwerty.CraftGuide.api;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Uses reflection to register itself with CraftGuide when created.
* <br><br>
* You do not need to use this class, it is provided only for convenience,
* as the static method it calls will accept any Object that implements
* zero or more of the following interfaces:
* <li>{@link RecipeProvider}
*/
public class CraftGuideAPIObject
{
/**
* When an instance of this class is created, it immediately registers itself
* with CraftGuide (through a static method, invoked through reflection).
* <br><br>
* If you don't want to extend this class, you need to use the code similar to
* this in order for CraftGuide to know that your object exists.
*/
public CraftGuideAPIObject()
{
try
{
Class c = Class.forName("uristqwerty.CraftGuide.ReflectionAPI");
Method m = c.getMethod("registerAPIObject", Object.class);
m.invoke(null, this);
}
catch(ClassNotFoundException e)
{
}
catch(NoSuchMethodException e)
{
}
catch(SecurityException e)
{
}
catch(InvocationTargetException e)
{
}
catch(IllegalAccessException e)
{
}
catch(IllegalArgumentException e)
{
}
}
}
@@ -0,0 +1,103 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
import net.minecraft.item.ItemStack;
/**
* An instance of a single recipe to be displayed by CraftGuide.
* <br><br>
* Contains a number of methods related to searching, drawing,
* and interaction with the user.
* <br><br>
* It is possible to implement your own recipe, if the default
* functionality is not adequate, although you won't have access
* to any of the default implementation, so it may require a bit
* of work.
*/
public interface CraftGuideRecipe
{
/**
* Checks whether a certain item is contained in this recipe.
* <br><br>
* This method is provided as a convenience for anyone writing a
* RecipeFilter; {@link #containsItem(ItemFilter)} will generally
* be used elsewhere.
* @param filter
* @return
*/
public boolean containsItem(ItemStack filter);
/**
* Checks whether this recipe contains an item that matches the
* supplied ItemFilter. Implementations of RecipeFilter may either
* use this or {@link #containsItem(ItemFilter)}; CraftGuide itself
* always uses this.
* @param filter
* @return
*/
public boolean containsItem(ItemFilter filter);
/**
* When a mouse click occurs within the rectangle occupied by this recipe,
* this method is used to determine if the current ItemFilter should be
* changed as a result. Generally involves iterating over each Slot within
* the recipe, and, if any of them is at the coordinates, returning
* {@link Slot#getClickedFilter}.
* @param x coordinate, relative to the top left of this recipe
* @param y coordinate, relative to the top left of this recipe
* @return a new ItemFilter, or null to keep the current one
*/
public ItemFilter getRecipeClickedResult(int x, int y);
/**
* Draws this recipe at the specified screen coordinates. If isMouseOver
* is true, mouseX and moyseY are the coordinates of the user's curosr,
* relative to the top left of this recipe; otherwise they are undefined,
* and may be anything, depending on the implementation of CraftGuide,
* and may change between CraftGuide versions.
* @param renderer
* @param x
* @param y
* @param isMouseOver
* @param mouseX
* @param mouseY
*/
public void draw(Renderer renderer, int x, int y, boolean isMouseOver, int mouseX, int mouseY);
/**
* Called to get the text to display when the user moves their cursor
* over this recipe. Generally, and in the default recipe implementation,
* this means checking if the cursor is over a Slot, and if so,
* returning whatever the slot returns for {@link Slot#getTooltip}
* @param mouseX
* @param mouseY
* @return a List of Strings, or null
*/
public List<String> getItemText(int mouseX, int mouseY);
/**
* Gets an array of Objects, representing the contents of this recipe.
* <br><br>
* Currently used by craftGuide to create a list of every type of item
* that is used (CraftGuide does not have any logic for finding items
* on its own). Some recipe filters may use this, although
* {@link containsItem} is preferred wherever possible.
* @return
*/
public Object[] getItems();
/**
* Gets the width of this recipe; used to determine grid spacing and
* if the cursor is currently positioned over this recipe
* @return
*/
public int width();
/**
* Gets the height of this recipe; used to determine grid spacing and
* if the cursor is currently positioned over this recipe
* @return
*/
public int height();
}
@@ -0,0 +1,15 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
/**
* Contains two forgotten methods from CraftGuideRecipe. Allows
* searching for items, limiting the search to a specific
* SlotType.
*/
public interface CraftGuideRecipeExtra1
{
public boolean containsItem(ItemStack filter, SlotType type);
public boolean containsItem(ItemFilter filter, SlotType type);
}
@@ -0,0 +1,126 @@
package uristqwerty.CraftGuide.api;
import java.util.ArrayList;
import java.util.List;
public class EUSlot implements Slot
{
public static final int VALUE_UNSPECIFIED = Integer.MIN_VALUE;
private int constantValue = VALUE_UNSPECIFIED;
private int constantSize = VALUE_UNSPECIFIED;
private final int x, y;
private final static int width = 16;
private final static int height = 16;
private static NamedTexture image;
public EUSlot(int x, int y)
{
this.x = x;
this.y = y;
if(image == null)
{
image = Util.instance.getTexture("EU-icon");
}
}
@Override
public void draw(Renderer renderer, int recipeX, int recipeY, Object[] data, int dataIndex, boolean isMouseOver)
{
renderer.renderRect(recipeX + x, recipeY + y, width, height, image);
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
return null;
}
@Override
public boolean isPointInBounds(int x, int y, Object[] data, int dataIndex)
{
return x >= this.x && x < this.x + width
&& y >= this.y && y < this.y + height;
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
int value = EUVaue(data[dataIndex]);
int size = PacketSize(data[dataIndex]);
ArrayList<String> tooltip = new ArrayList<String>();
tooltip.add("\u00a7fIC2 energy");
if(value != -1)
{
tooltip.add("\u00a77 " + Math.abs(value) + " EU " + (value > 0? "produced" : "used"));
}
if(size != -1)
{
tooltip.add("\u00a77 " + size + " EU/t");
}
return tooltip;
}
@Override
public boolean matches(ItemFilter filter, Object[] data, int dataIndex, SlotType type)
{
return false;
}
public int EUVaue(Object data)
{
if(data instanceof Object[] && ((Object[])data)[0] instanceof Integer)
{
return (Integer)((Object[])data)[0];
}
else if(constantValue != VALUE_UNSPECIFIED)
{
return constantValue;
}
else if(data instanceof Integer)
{
return (Integer)data;
}
else
{
return VALUE_UNSPECIFIED;
}
}
public int PacketSize(Object data)
{
if(data instanceof Object[] && ((Object[])data)[1] instanceof Integer)
{
return (Integer)((Object[])data)[1];
}
else if(constantSize != VALUE_UNSPECIFIED)
{
return constantSize;
}
else if(data instanceof Integer)
{
return (Integer)data;
}
else
{
return VALUE_UNSPECIFIED;
}
}
public EUSlot setConstantEUValue(int value)
{
constantValue = value;
return this;
}
public EUSlot setConstantPacketSize(int size)
{
constantSize = size;
return this;
}
}
@@ -0,0 +1,106 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
* An extension of ItemSlot that allows certain interactions
* to be disabled, and uses fixed Object provided during
* initialisation rather than the object matching this slot
* in the recipe.
* <br><br>
* Unlike in the old API, there is no "can filter" option,
* as that can be accomplished through {@link #setSlotType}
* which is already present in ItemSlot.
*/
public class ExtraSlot extends ItemSlot
{
public Object displayed;
public boolean showName = false;
public boolean canClick = false;
public ExtraSlot(int x, int y, int width, int height, Object displayedItem)
{
super(x, y, width, height);
displayed = displayedItem;
}
@Override
public void draw(Renderer renderer, int x, int y, Object[] data, int dataIndex, boolean isMouseOver)
{
implementation.draw(this, renderer, x, y, displayed, canClick && isMouseOver);
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
if(showName)
{
return implementation.getTooltip(this, displayed);
}
else
{
return null;
}
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
if(canClick)
{
return implementation.getClickedFilter(x, y, displayed);
}
else
{
return null;
}
}
/**
* Sets whether this slot, if clicked, sets the current
* filter to the displayed Object, or doesn't do anything
*
* @param clickable
* @return this ExtraSlot, to permit method chaining
*/
public ExtraSlot clickable(boolean clickable)
{
canClick = clickable;
return this;
}
/**
* Sets whether this slot shows a tooltip on mouseover
*
* @param showName
* @return this ExtraSlot, to permit method chaining
*/
public ExtraSlot showName(boolean showName)
{
this.showName = showName;
return this;
}
/**
* A shortened version of {@link #clickable(boolean)}
* that passes true
*
* @return this ExtraSlot, to permit method chaining
*/
public ExtraSlot clickable()
{
return clickable(true);
}
/**
* A shortened version of {@link #showName(boolean)}
* that passes true
*
* @return this ExtraSlot, to permit method chaining
*/
public ExtraSlot showName()
{
return showName(true);
}
}
@@ -0,0 +1,74 @@
package uristqwerty.CraftGuide.api;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemStack;
public class InfoSlot extends ItemSlot
{
private final ItemStack displayed;
private final String[] format;
private boolean clickable;
private boolean searchable;
public InfoSlot(int x, int y, ItemStack displayedStack, String[] lines)
{
super(x, y, 16, 16, true);
displayed = displayedStack;
format = lines;
}
@Override
public void draw(Renderer renderer, int x, int y, Object[] data, int dataIndex, boolean isMouseOver)
{
ItemSlot.implementation.draw(this, renderer, x, y, displayed, isMouseOver && clickable);
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
return clickable? null : ItemSlot.implementation.getClickedFilter(x, y, displayed);
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
List<String> tooltip = new ArrayList<String>();
if(data[dataIndex] instanceof Object[])
{
for(int i = 0; i < format.length; i++)
{
tooltip.add(String.format(format[i], (Object[])data[dataIndex]));
}
}
else
{
for(int i = 0; i < format.length; i++)
{
tooltip.add(String.format(format[i], data[dataIndex]));
}
}
return tooltip;
}
@Override
public boolean matches(ItemFilter filter, Object[] data, int dataIndex, SlotType type)
{
return searchable && ItemSlot.implementation.matches(this, filter, displayed, type);
}
public InfoSlot setSeachable(boolean searchable)
{
this.searchable = searchable;
return this;
}
public InfoSlot setClickable(boolean clickable)
{
this.clickable = clickable;
return this;
}
}
@@ -0,0 +1,37 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
*
*/
public interface ItemFilter
{
/**
* Compares this filter with an Object. Common types include an
* ItemStack, a List of ItemStacks, or a String.
* <br><br>
* If the object type is unknown, return false.
* @param item
* @return
*/
public boolean matches(Object item);
/**
* Draw a visual representation of this filter at (x, y), within a
* 16 by 16 rectangle. May extend out of that rectangle, although it
* might not look very good.
* @param renderer
* @param x
* @param y
*/
public void draw(Renderer renderer, int x, int y);
/**
* Gets a description of the filter, displayed when the user moves
* their cursor over the filter display.
* @return a List of lines of text
*/
public List<String> getTooltip();
}
@@ -0,0 +1,154 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
* When a recipe is rendered, the ItemSlots provided to the template are
* used to determine the layout of the recipe's items.
*/
public class ItemSlot implements Slot
{
/**
* This slot's size and location relative to the containing
* recipe's top left corner
*/
public int x, y, width, height;
/**
* Used by {@link ItemSlotImplementation#draw} to decide
* whether to draw a background before drawing the actual
* slot contents.
*/
public boolean drawBackground;
/**
* A sneaky field that is read by the default recipe implementation
* when an instance is created. If an ItemStack with a quantity
* greater than one would match up to an ItemSlot where
* drawQuantity equals false, it replaces the stack with one
* with a size of 1. This is only provided for convenience, it
* is entirely possibly to implement the same logic if it
* is needed but unavailable, such as with a custom recipe,
* or an implementation of Slot that is not an ItemSlot.
* <br><br>
* The actual effect of this field may change in the future
* (for example, copying only part of the method that Minecraft
* uses to draw the item overlay, making the part that draws the
* stack size conditional), but for the moment, I'm assuming that
* doing it this way will be more compatible if Minecraft changes
* its implementation in the future, or if another mod edits
* {@link net.minecraft.src.RenderItem#renderItemOverlayIntoGUI}.
*/
public boolean drawQuantity;
/**
* Used by {@link ItemSlotImplementation#matches} to
* restrict what sort of searches can match this slot
*/
public SlotType slotType = SlotType.INPUT_SLOT;
/**
* Implementation of ItemSlot functionality, allowing it
* to change if needed, without altering the API. This
* field is set during CraftGuide's {@literal @PreInit}.
*/
public static ItemSlotImplementation implementation;
/**
* Creates a new ItemSlot. Same as
* {@link #ItemSlot(int, int, int, int, boolean)}, with
* false as the last parameter.
* @param x
* @param y
* @param width
* @param height
*/
public ItemSlot(int x, int y, int width, int height)
{
this(x, y, width, height, false);
}
/**
* Creates a new ItemSlot
* @param x
* @param y
* @param width
* @param height
* @param drawQuantity
*/
public ItemSlot(int x, int y, int width, int height, boolean drawQuantity)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.drawQuantity = drawQuantity;
}
@Override
public void draw(Renderer renderer, int x, int y, Object[] data, int dataIndex, boolean isMouseOver)
{
implementation.draw(this, renderer, x, y, data[dataIndex], isMouseOver);
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
return implementation.getTooltip(this, data[dataIndex]);
}
@Override
public boolean matches(ItemFilter search, Object[] data, int dataIndex, SlotType type)
{
return implementation.matches(this, search, data[dataIndex], type);
}
@Override
public boolean isPointInBounds(int x, int y, Object[] data, int dataIndex)
{
return implementation.isPointInBounds(this, x, y);
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
return implementation.getClickedFilter(x, y, data[dataIndex]);
}
/**
* Sets whether or not this ItemSlot draws a background square
* during its draw method.
* @param draw
* @return this, to permit method chaining
*/
public ItemSlot drawOwnBackground(boolean draw)
{
drawBackground = draw;
return this;
}
/**
* Sets whether or not this ItemSlot draws a background square
* during its draw method. Same as {@link #drawOwnBackground()},
* but uses the default value of true.
* @return this, to permit method chaining
*/
public ItemSlot drawOwnBackground()
{
return drawOwnBackground(true);
}
/**
* Sets the {@link SlotType} associated with this ItemSlot.
* The SlotType is used for searches, both from in-game, and
* from the use of the API
* @param type
* @return this ItemSlot, to permit method chaining
*/
public ItemSlot setSlotType(SlotType type)
{
slotType = type;
return this;
}
}
@@ -0,0 +1,61 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
* A collections of methods implementing the functionality required
* by ItemStack, without needing the code to be included as part of
* the API.
*/
public interface ItemSlotImplementation
{
/**
* Gets the tooltip for an ItemSlot
* @param itemSlot
* @param data
* @return
*/
public List<String> getTooltip(ItemSlot itemSlot, Object data);
/**
* Draws an ItemSlot.
* @param itemSlot
* @param renderer
* @param x
* @param y
* @param data
* @param isMouseOver
*/
public void draw(ItemSlot itemSlot, Renderer renderer, int x, int y, Object data, boolean isMouseOver);
/**
* Return an ItemFilter representing the ItemSlot contents.
* @param x
* @param y
* @param object
* @return
*/
public ItemFilter getClickedFilter(int x, int y, Object object);
/**
* Compare the contents of an ItemSlot with an ItemFilter.
* @param itemSlot
* @param search
* @param object
* @param type
* @return
*/
public boolean matches(ItemSlot itemSlot, ItemFilter search, Object object, SlotType type);
/**
* Does some simple math to test if a point, relative to the containing
* recipe's top left corner, is within the boundary rectangle of an
* ItemSlot.
* @param itemSlot
* @param x
* @param y
* @return
*/
public boolean isPointInBounds(ItemSlot itemSlot, int x, int y);
}
@@ -0,0 +1,117 @@
package uristqwerty.CraftGuide.api;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
public class LiquidFilter implements ItemFilter
{
private static NamedTexture containerTexture = null;
private FluidStack liquid;
private String liquidName;
private List<String> tooltip = new ArrayList<String>();
public LiquidFilter(FluidStack liquid)
{
if(containerTexture == null)
{
containerTexture = Util.instance.getTexture("liquidFilterContainer");
}
setLiquid(liquid);
}
public void setLiquid(FluidStack liquid)
{
String name = liquid.getFluid().getLocalizedName();
this.liquid = liquid;
liquidName = name.toLowerCase();
tooltip.clear();
tooltip.add(name);
}
@Override
public boolean matches(Object item)
{
if(item instanceof ItemStack)
{
return liquid.isFluidEqual((ItemStack)item);
}
else if(item instanceof FluidStack)
{
return liquid.isFluidEqual((FluidStack)item);
}
else if(item instanceof String)
{
return liquidName.contains(((String)item).toLowerCase());
}
else if(item instanceof List)
{
for(Object object: ((List)item))
{
if(matches(object))
{
return true;
}
}
}
return false;
}
@Override
public void draw(Renderer renderer, int x, int y)
{
if(liquid != null)
{
TextureManager textureManager = Minecraft.getMinecraft().getTextureManager();
Fluid fluid = liquid.getFluid();
IIcon icon = fluid.getStillIcon();
if(icon != null)
{
textureManager.bindTexture(TextureMap.locationBlocksTexture);
double u = icon.getInterpolatedU(3.0);
double u2 = icon.getInterpolatedU(13.0);
double v = icon.getInterpolatedV(1.0);
double v2 = icon.getInterpolatedV(15.0);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glColor4d(1.0, 1.0, 1.0, 1.0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(u, v);
GL11.glVertex2i(x + 3, y + 1);
GL11.glTexCoord2d(u, v2);
GL11.glVertex2i(x + 3, y + 15);
GL11.glTexCoord2d(u2, v2);
GL11.glVertex2i(x + 13, y + 15);
GL11.glTexCoord2d(u2, v);
GL11.glVertex2i(x + 13, y + 1);
GL11.glEnd();
}
}
renderer.renderRect(x - 1, y - 1, 18, 18, containerTexture);
}
@Override
public List<String> getTooltip()
{
return tooltip;
}
}
@@ -0,0 +1,158 @@
package uristqwerty.CraftGuide.api;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.IIcon;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
public class LiquidSlot implements Slot
{
private int x;
private int y;
private int width = 16;
private int height = 16;
private SlotType slotType = SlotType.INPUT_SLOT;
private static NamedTexture containerTexture = null;
public LiquidSlot(int x, int y)
{
this.x = x;
this.y = y;
if(containerTexture == null)
{
containerTexture = Util.instance.getTexture("liquidFilterContainer");
}
}
@Override
public void draw(Renderer renderer, int recipeX, int recipeY, Object[] data, int dataIndex, boolean isMouseOver)
{
int x = recipeX + this.x;
int y = recipeY + this.y;
if(data[dataIndex] instanceof FluidStack)
{
FluidStack liquid = (FluidStack)data[dataIndex];
TextureManager textureManager = Minecraft.getMinecraft().getTextureManager();
Fluid fluid = liquid.getFluid();
IIcon icon = fluid.getStillIcon();
if(icon != null)
{
textureManager.bindTexture(TextureMap.locationBlocksTexture);
double u = icon.getInterpolatedU(3.0);
double u2 = icon.getInterpolatedU(13.0);
double v = icon.getInterpolatedV(1.0);
double v2 = icon.getInterpolatedV(15.0);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glColor4d(1.0, 1.0, 1.0, 1.0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2d(u, v);
GL11.glVertex2i(x + 3, y + 1);
GL11.glTexCoord2d(u, v2);
GL11.glVertex2i(x + 3, y + 15);
GL11.glTexCoord2d(u2, v2);
GL11.glVertex2i(x + 13, y + 15);
GL11.glTexCoord2d(u2, v);
GL11.glVertex2i(x + 13, y + 1);
GL11.glEnd();
}
}
renderer.renderRect(x - 1, y - 1, 18, 18, containerTexture);
}
@Override
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex)
{
if(data[dataIndex] instanceof FluidStack)
{
return new LiquidFilter((FluidStack)data[dataIndex]);
}
else
{
return null;
}
}
@Override
public boolean isPointInBounds(int x, int y, Object[] data, int dataIndex)
{
return x >= this.x && x < this.x + width
&& y >= this.y && y < this.y + height;
}
@Override
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex)
{
List<String> tooltip = null;
if(data[dataIndex] instanceof FluidStack)
{
tooltip = new ArrayList<String>(1);
FluidStack stack = (FluidStack)data[dataIndex];
tooltip.add(stack.getFluid().getLocalizedName() + " (" + stack.amount + " milliBuckets)");
}
return tooltip;
}
//Check if the filter directly matches the contained LiquidStack, or
// matches any liquid container containing the liquid.
@Override
public boolean matches(ItemFilter filter, Object[] data, int dataIndex, SlotType type)
{
if(!(data[dataIndex] instanceof FluidStack) ||
(type != slotType && (
type != SlotType.ANY_SLOT ||
slotType == SlotType.DISPLAY_SLOT ||
slotType == SlotType.HIDDEN_SLOT)))
{
return false;
}
FluidStack stack = (FluidStack)data[dataIndex];
if(filter.matches(stack))
{
return true;
}
else
{
for(FluidContainerData liquidData: FluidContainerRegistry.getRegisteredFluidContainerData())
{
if(stack.isFluidEqual(liquidData.fluid) && filter.matches(liquidData.filledContainer))
{
return true;
}
}
return false;
}
}
public Slot setSlotType(SlotType type)
{
slotType = type;
return this;
}
}
@@ -0,0 +1,11 @@
package uristqwerty.CraftGuide.api;
/**
* This interface represents an internal object to be used with
* {@link Renderer#renderRect(int, int, int, int, NamedTexture)}.
* It exists only to provide a type-safe way of storing the objects
* returned by {@link Util#getTexture}.
*/
public interface NamedTexture
{
}
@@ -0,0 +1,24 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
import net.minecraft.item.ItemStack;
/**
* More advanced than {@link BasicRecipeFilter}, this
* interface also allows re-ordering and insertion of
* entirely new recipes for each recipe type.
*/
public interface RecipeFilter
{
/**
* Given a List of {@link CraftGuideRecipe}s, returns a
* modified list. May either return the provided list, or
* create a new List object. If a new List is created, it
* must allow element removal from its iterator.
* @param source
* @param recipeType
* @return
*/
public List<CraftGuideRecipe> filterRecipes(List<CraftGuideRecipe> source, ItemStack recipeType);
}
@@ -0,0 +1,120 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
/**
* This interface contains methods that can be used to provide CraftGuide with
* crafting recipes.
* <br><br>
* To do so, use one of the methods returning an {@link RecipeTemplate}
* to create a template from a list of {@link ItemSlot}s and optionally an
* ItemStack representing the recipe type (generally the block/item used to
* craft the recipe, if not provided, defaults to the workbench).
* <br><br>
* With the template, call addRecipe for each recipe, passing an ItemStack[]
* corresponding to the ItemSlot[] provided when creating the template.
*/
public interface RecipeGenerator
{
/**
* Creates a {@link RecipeTemplate} for the provided ISlot[],
* associated with the provided crafting type. Create a default
* background based on the size of the template.
* @param slots
* @param craftingType
* @return
*/
public RecipeTemplate createRecipeTemplate(Slot[] slots, ItemStack craftingType);
/**
* Creates a {@link RecipeTemplate} for the provided ISlot[],
* associated with the provided crafting type. The background is
* a rectangle taken out of the supplied texture file, at the
* coordinate pairs given.
* @param slots
* @param craftingType
* @param backgroundTexture
* @param backgroundX
* @param backgroundY
* @param backgroundSelectedX
* @param backgroundSelectedY
* @return
*/
public RecipeTemplate createRecipeTemplate(Slot[] slots, ItemStack craftingType, String backgroundTexture, int backgroundX, int backgroundY, int backgroundSelectedX, int backgroundSelectedY);
/**
* Creates a {@link RecipeTemplate} for the provided ISlot[],
* associated with the provided crafting type. The background is
* a rectangle taken out of the supplied texture file, at the
* coordinate pairs given.
* @param slots
* @param craftingType
* @param backgroundTexture
* @param backgroundX
* @param backgroundY
* @param backgroundSelectedTexture
* @param backgroundSelectedX
* @param backgroundSelectedY
* @return
*/
public RecipeTemplate createRecipeTemplate(Slot[] slots, ItemStack craftingType, String backgroundTexture, int backgroundX, int backgroundY, String backgroundSelectedTexture, int backgroundSelectedX, int backgroundSelectedY);
/**
* Generates a recipe from the template and Object[] passed to
* this method, and then adds it to CraftGuide to display in
* game.
* @param template
* @param crafting
*/
public void addRecipe(RecipeTemplate template, Object[] crafting);
/**
* If you have your own recipe implementation, you can use this
* method to add recipes without needing a RecipeTemplate.
* @param recipe
* @param craftingType
*/
public void addRecipe(CraftGuideRecipe recipe, ItemStack craftingType);
/**
* Sets whether a certain type of recipe is initially visible.
* <br><br>
* Useful for hiding recipe types that have a lot of recipes, but
* few people need, so they would normally just add excessive
* clutter to the recipe list.
* @param type an ItemStack associated with the recipe type
* @param visible whether it is initially visible or not
*/
public void setDefaultTypeVisibility(ItemStack type, boolean visible);
/**
* Takes an IRecipe, and returns an array representing a
* 3x3 crafting grid, plus a single output, for that recipe's
* contents. Each element is either null, an ItemStack, or a
* List containing zero or more ItemStacks (for Forge ore
* dictionary recipes).
* <br><br>
* May return null if given an IRecipe implementation that it
* cannot interpret.
* @see #getCraftingRecipe(IRecipe, boolean)
* @param recipe the IRecipe to be read
* @return an Object[10], where the first nine elements form
* the 3x3 input grid, and the last element is the recipe output.
*/
public Object[] getCraftingRecipe(IRecipe recipe);
/**
* Takes an IRecipe, and returns an array representing a
* 3x3 or 2x2 crafting grid, plus a single output.
* <br><br>
* See {@link #getCraftingRecipe(IRecipe)} for details.
* @see #getCraftingRecipe(IRecipe)
* @param recipe
* @param allowSmallGrid if true, may return an Object[5] if
* the recipe fits in a 2x2 grid.
* @return an Object[10] or an Object[5]
*/
public Object[] getCraftingRecipe(IRecipe recipe, boolean allowSmallGrid);
}
@@ -0,0 +1,18 @@
package uristqwerty.CraftGuide.api;
/**
* When CraftGuide (re)loads its recipe list, every Object that implements this
* interface, and has been registered with CraftGuide, will have its generateRecipes
* method called.
*/
public interface RecipeProvider
{
/**
* Called by CraftGuide when it is (re)populating its recipe list, as a request
* for the implementing Object to provide recipes through the RecipeGenerator
* instance passed to it.
* @param generator
* @see RecipeGenerator
*/
void generateRecipes(RecipeGenerator generator);
}
@@ -0,0 +1,36 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
/**
*/
public interface RecipeTemplate
{
/**
* Sets the width and height that will be used for recipes
* produced by this template
* @param width
* @param height
* @return this template, to allow method chaining
*/
public RecipeTemplate setSize(int width, int height);
/**
* Gets an ItemStack that represents the type of the recipe.
* Generally, this should be the block or item that players
* would most closely associate with it, such as the machine
* that the recipe is crafted in, or an item that opens the
* crafting GUI used by the recipe.
*
* @return the ItemStack, or null to default to a workbench
*/
public ItemStack getCraftingType();
/**
* Generate a recipe from an Object[] representing the contents
* of the recipe.
* @param items
* @return
*/
public CraftGuideRecipe generate(Object[] items);
}
@@ -0,0 +1,108 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
/**
* Provides useful methods to render common things, in
* {@link Slot#draw} and {@link CraftGuideRecipe#draw}.
*/
public interface Renderer
{
/**
* Draws an ItemStack at the specified screen coordinates.
* @param x
* @param y
* @param stack
*/
public void renderItemStack(int x, int y, ItemStack stack);
/**
* Draws a solid color rectangle
* @param x
* @param y
* @param width
* @param height
* @param color_argb Red, Green, Blue, and Alpha, packed into a single int,
* in the form 0xaarrggbb
*/
public void renderRect(int x, int y, int width, int height, int color_argb);
/**
* Draws a solid color rectangle
* @param x
* @param y
* @param width
* @param height
* @param color_rgb Red, Green, and Blue, packed into a single int, in the
* form 0x00rrggbb
* @param alpha
*/
public void renderRect(int x, int y, int width, int height, int color_rgb, int alpha);
/**
* Draws a solid color rectangle
* @param x
* @param y
* @param width
* @param height
* @param red
* @param green
* @param blue
* @param alpha
*/
public void renderRect(int x, int y, int width, int height, int red, int green, int blue, int alpha);
/**
* Draws a rectangle, textured with a NamedTexture obtained from
* {@link Util#getTexture}.
* @param x
* @param y
* @param width
* @param height
* @param texture
*/
public void renderRect(int x, int y, int width, int height, NamedTexture texture);
/**
* Draws a rectangle, containing a vertical gradient
* <br>
* Colors are packed into ints, in the form 0xaarrggbb
* @param x
* @param y
* @param width
* @param height
* @param topColor_argb
* @param bottomColor_argb
*/
public void renderVerticalGradient(int x, int y, int width, int height, int topColor_argb, int bottomColor_argb);
/**
* Draws a rectangle, containing a horizontal gradient.
* <br>
* Colors are packed into ints, in the form 0xaarrggbb
* @param x
* @param y
* @param width
* @param height
* @param leftColor_argb
* @param rightColor_argb
*/
public void renderHorizontalGradient(int x, int y, int width, int height, int leftColor_argb, int rightColor_argb);
/**
* Draws a rectangle, containing an arbitrary gradient.
* <br>
* Colors are packed into ints, in the form 0xaarrggbb
* @param x
* @param y
* @param width
* @param height
* @param topLeftColor_argb
* @param topRightColor_argb
* @param bottomLeftColor_argb
* @param bottomRightColor_argb
*/
public void renderGradient(int x, int y, int width, int height, int topLeftColor_argb, int topRightColor_argb, int bottomLeftColor_argb, int bottomRightColor_argb);
}
@@ -0,0 +1,92 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
/**
* A Slot represents a single component of a recipe being displayed by
* CraftGuide. Similar to how Minecraft handles items and blocks, one
* instance of a slot is used to handle the logic of multiple recipes.
* <br><br>
* Each method's parameters include an Object[] representing the specific
* recipe, and the index of the Object related to this slot, allowing
* implementations that react differently based on more than one component
* of the recipe.
* <br><br>
* Slot is only used by the default implementation of CraftGuideRecipe, a
* custom implementation may opt to ignore any part of this, or not use it
* entirely, but if it does, then it should provide some sort of logic to
* perform the same functionality. For example, one mod may opt to extend
* this interface with a number of more specific methods, and implement a
* recipe that mainly uses the alternate methods in certain situations.
* For most mods, however, the existing recipe mechanics should be
* sufficient (most shouldn't even need more than the provided ItemSlot).
*/
public interface Slot
{
/**
* This method is called in order to draw this slot. (x, y) is the
* absolute coordinate of the top left corner of the containing
* recipe.
* @param renderer
* @param x
* @param y
* @param data
* @param dataIndex
* @param isMouseOver
*/
public void draw(Renderer renderer, int x, int y, Object[] data, int dataIndex, boolean isMouseOver);
/**
* When this slot is clicked on in a recipe, this method is called in
* order to get the filter Object that is used to search the recipe list
* for related recipes. If null is returned, then the filter will not
* change.
* <br><br>
* For common types, {@link Util#getCommonFilter(Object)} can provide
* a filter if given a known type of Object.
* @param x clicked coordinate, relative to the recipe's top left corner
* @param y clicked coordinate, relative to the recipe's top left corner
* @param data the Object[] representing the recipe
* @param dataIndex this slot's index in data
* @return null, or an IItemFilter
*/
public ItemFilter getClickedFilter(int x, int y, Object[] data, int dataIndex);
/**
* This method is used by CraftGuide to determine whether a specific point
* is considered within the bounds of this particular slot. It is typically
* used to determine what slot, if any, the user's cursor is currently over.
*
* @param x coordinate, relative to the recipe's top left corner
* @param y coordinate, relative to the recipe's top left corner
* @param data the Object[] representing the recipe
* @param dataIndex this slot's index in data
* @return true if (x, y) is within this slot's bounds, otherwise false
*/
public boolean isPointInBounds(int x, int y, Object[] data, int dataIndex);
/**
* When the user moves their cursor over a recipe containing this slot, and
* the cursor's position is within the bounds of this slot (relative to the
* containing recipe), this method is called to determine whether to display
* a tooltip, and, if so, what text should be displayed.
*
* @param x cursor coordinate, relative to the recipe's top left corner
* @param y cursor coordinate, relative to the recipe's top left corner
* @param data the Object[] representing the recipe
* @param dataIndex this slot's index in data
* @return a List of Strings, representing one or more lines of text, or
* null if the tooltip should not be displayed
*/
public List<String> getTooltip(int x, int y, Object[] data, int dataIndex);
/**
* Used to test if a specific slot matches the searched {@link ItemFilter}
*
* @param filter the Object being compared the the contents of this slot
* @param data the recipe's raw data array
* @param dataIndex this slot's index
* @param type the type of slot that is being searched for
*/
public boolean matches(ItemFilter filter, Object[] data, int dataIndex, SlotType type);
}
@@ -0,0 +1,38 @@
package uristqwerty.CraftGuide.api;
/**
* SlotType is used to declare the purpose of a {@link Slot}, used
* by searches (both in-game and through the API).
*/
public enum SlotType
{
/**
* For searches; matches anything except
* {@link HIDDEN_SLOT} and {@link DISPLAY_SLOT}
*/
ANY_SLOT,
/** Resources required for the recipe */
INPUT_SLOT,
/** Products produced by the recipe */
OUTPUT_SLOT,
/** Machine(s) that processes the recipe */
MACHINE_SLOT,
/**
* Just in case {@link INPUT_SLOT}, {@link OUTPUT_SLOT},
* and {@link MACHINE_SLOT} aren't adequate descriptions
* of this slot's purpose.
*/
OTHER_SLOT,
/**
* Does not show up in searches for {@link ANY_SLOT}.
* Use for visual effects and such.
*/
DISPLAY_SLOT,
/**
* Does not show up in searches for {@link ANY_SLOT}.
*/
HIDDEN_SLOT,
}
@@ -0,0 +1,21 @@
package uristqwerty.CraftGuide.api;
import java.util.ArrayList;
import java.util.List;
/**
* Contains a list of objects polled by CraftGuide every time the
* tooltip text of an item is needed, allowing additional lines
* of information about the stack to be displayed.
*
* @see StackInfoSource
*/
public class StackInfo
{
public static List<StackInfoSource> sources = new ArrayList<StackInfoSource>();
public static void addSource(StackInfoSource source)
{
sources.add(source);
}
}
@@ -0,0 +1,17 @@
package uristqwerty.CraftGuide.api;
import net.minecraft.item.ItemStack;
/**
* When CraftGuide gets the tooltip of an item, every StackInfoSource
* listed by {@link StackInfo} is polled, so that it may provide
* additional lines of information about the stack.
*/
public interface StackInfoSource
{
/**
* May return null to indicate that no additional information
* about the stack is provided by this StackInfoSource.
*/
public String getInfo(ItemStack itemStack);
}
@@ -0,0 +1,90 @@
package uristqwerty.CraftGuide.api;
import java.util.List;
import net.minecraft.item.ItemStack;
/**
* Contains a number of methods that implement common functionality
* that would otherwise need to be implemented by everyone who uses
* the API, or that relies on parts of CraftGuide not included in
* the API.
*/
public abstract class Util
{
/**
* An instance of Util, containing the method implementations.
* <br><br>
* It is set during CraftGuide's {@literal @PreInit}.
*/
public static Util instance;
/**
* Causes CraftGuide to clear its list of recipes, and reload them with
* exactly the same process that was originally used to build the list.
*/
public abstract void reloadRecipes();
/**
* Converts the passed ItemStack's name and information into a List
* of Strings for display, similar to how GuiContainer does it.
* Additionally, contains logic to try an alternative if given a stack
* with a damage of -1 which produces an unusable name and information,
* if CraftGuide is set to always show item IDs it will insert the item's
* ID and damage value as the second line. If an exception is thrown
* at any time during the process, it will log it to CraftGuide.log and
* generate an error text to display that at least shows the item ID and
* damage.
* @param stack
* @return
*/
public abstract List<String> getItemStackText(ItemStack stack);
/**
* Gets a standard {@link ItemFilter} for any of the common types:
* <li>ItemStack
* <li>List of ItemStacks
* <li>String
*
* @param item
* @return
*/
public abstract ItemFilter getCommonFilter(Object item);
/**
* Gets a texture usable with {@link Renderer#renderRect}
* from a String identifier.
* If the texture does not exist in the current theme, nothing will be drawn.
* <br><br>
* In addition to anything defined by the
* currently-active theme, converts the following aliases to the equivalent
* name used in theme files for backwards compatibility:
*
* <li>"ItemStack-Any": ItemStack overlay indicating that any metadata value
* matches</li>
* <li>"ItemStack-OreDict": ItemStack overlay indicating that any one of a
* list of ItemStacks are acceptable.</li>
* <li>"ItemStack-OreDict-Single": Used in place of ItemStack-OreDict when
* the list of ItemStacks is exactly one element long.</li>
* <li>"ItemStack-Background": Image used as background for GUI slots</li>
* <li>"TextFilter": Icon used in place of an ItemStack when searching for
* a String</li>
* <li>"Error": Displayed in place of an ItemStack when an error prevents
* that stack from being rendered.</li>
*
* @param identifier
* @return
*/
public abstract NamedTexture getTexture(String identifier);
/**
* Returns the number of partial ticks for this frame. I don't know
* quite what they do, but it's the third parameter to
* {@link net.minecraft.src.GuiScreen#drawScreen}, so I'm assuming
* that at least something needs it. Rather than pass it as an
* extra argument to every drawing method, it is stored at the
* start of rendering the GUI, and can be retrieved with this method.
* @return
*/
public abstract float getPartialTicks();
}