Updating Thaumcraft API to the newest version.

This commit is contained in:
Amnet 2013-10-06 22:38:49 +02:00
parent 32d8351fea
commit d8f6e6d2ae
24 changed files with 469 additions and 440 deletions

View File

@ -7,7 +7,7 @@ package thaumcraft.api;
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IVisRepairable {
public interface IRepairable {
}

View File

@ -0,0 +1,17 @@
package thaumcraft.api;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
/**
* @author Azanor
* Items, armor and tools with this interface can receive the Repair enchantment.
* Repairs 1 point of durability every 10 seconds (2 for repair II)
*/
public interface IRepairableExtended extends IRepairable {
public boolean doRepair(ItemStack stack, EntityPlayer player, int enchantlevel);
}

View File

@ -19,17 +19,33 @@ public class ItemApi {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.Config";
String itemClass = "thaumcraft.common.config.ConfigItems";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Item) {
item = new ItemStack((Item) obj,1,meta);
} else if (obj instanceof Block) {
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve item identified by: " + itemString);
}
return item;
}
public static ItemStack getBlock(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.config.ConfigBlocks";
Object obj = Class.forName(itemClass).getField(itemString).get(null);
if (obj instanceof Block) {
item = new ItemStack((Block) obj,1,meta);
} else if (obj instanceof ItemStack) {
item = (ItemStack) obj;
}
} catch (Exception ex) {
FMLLog.warning("[Thaumcraft] Could not retrieve item or block identified by: " + itemString);
FMLLog.warning("[Thaumcraft] Could not retrieve block identified by: " + itemString);
}
return item;

View File

@ -1,58 +0,0 @@
package thaumcraft.api;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
public class MaterialTaint extends Material
{
public MaterialTaint(MapColor par1MapColor)
{
super(par1MapColor);
this.setNoPushMobility();
this.setRequiresTool();
}
@Override
public boolean isSolid()
{
return false;
}
@Override
public boolean isReplaceable()
{
return false;
}
/**
* Will prevent grass from growing on dirt underneath and kill any grass below it if it returns true
*/
@Override
public boolean getCanBlockGrass()
{
return false;
}
/**
* Returns if this material is considered solid or not
*/
@Override
public boolean blocksMovement()
{
return true;
}
@Override
protected Material setRequiresTool() {
// TODO Auto-generated method stub
return super.setRequiresTool();
}
@Override
public int getMaterialMobility() {
// TODO Auto-generated method stub
return super.getMaterialMobility();
}
}

View File

@ -6,8 +6,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumArmorMaterial;
import net.minecraft.item.EnumToolMaterial;
@ -17,7 +15,8 @@ import net.minecraftforge.common.EnumHelper;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.RecipeCrucible;
import thaumcraft.api.crafting.CrucibleRecipe;
import thaumcraft.api.crafting.InfusionRecipe;
import thaumcraft.api.crafting.ShapedArcaneRecipe;
import thaumcraft.api.crafting.ShapelessArcaneRecipe;
import thaumcraft.api.research.IScanEventHandler;
@ -41,8 +40,13 @@ public class ThaumcraftApi {
public static EnumToolMaterial toolMatElemental = EnumHelper.addToolMaterial("THAUMIUM_ELEMENTAL", 3, 1500, 10F, 3, 18);
public static EnumArmorMaterial armorMatThaumium = EnumHelper.addArmorMaterial("THAUMIUM", 25, new int[] { 2, 6, 5, 2 }, 25);
public static EnumArmorMaterial armorMatSpecial = EnumHelper.addArmorMaterial("SPECIAL", 25, new int[] { 1, 3, 2, 1 }, 25);
public static final Material fluxGoomaterial = (new MaterialTaint(MapColor.grassColor));
public static final Material taintMaterial = (new MaterialTaint(MapColor.grassColor));
//Enchantment references
public static int enchantFrugal;
public static int enchantPotency;
public static int enchantWandFortune;
public static int enchantHaste;
public static int enchantRepair;
//Miscellaneous
/**
@ -164,6 +168,41 @@ public class ThaumcraftApi {
craftingRecipes.add(r);
return r;
}
/**
* @param research the research key required for this recipe to work. Leave blank if it will work without research
* @param result the recipe output. It can either be an itemstack or an nbt compound tag that will be added to the central item
* @param instability a number that represents the N in 1000 chance for the infusion altar to spawn an
* instability effect each second while the crafting is in progress
* @param aspects the essentia cost per aspect.
* @param aspects input the central item to be infused
* @param recipe An array of items required to craft this. Input itemstacks are NBT sensitive.
* Infusion crafting components are automatically "fuzzy" and the oredict will be checked for possible matches.
*
*/
public static InfusionRecipe addInfusionCraftingRecipe(String research, Object result, int instability, AspectList aspects, ItemStack input,ItemStack[] recipe)
{
if (!(result instanceof ItemStack || result instanceof NBTBase)) return null;
InfusionRecipe r= new InfusionRecipe(research, result, instability, aspects, input, recipe);
craftingRecipes.add(r);
return r;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static InfusionRecipe getInfusionRecipe(ItemStack res) {
for (Object r:getCraftingRecipes()) {
if (r instanceof InfusionRecipe) {
if (((InfusionRecipe)r).recipeOutput instanceof ItemStack) {
if (((ItemStack) ((InfusionRecipe)r).recipeOutput).isItemEqual(res))
return (InfusionRecipe)r;
}
}
}
return null;
}
/**
@ -172,8 +211,8 @@ public class ThaumcraftApi {
* @param cost the vis cost
* @param tags the aspects required to craft this
*/
public static RecipeCrucible addCrucibleRecipe(String key, ItemStack result, Object catalyst, AspectList tags) {
RecipeCrucible rc = new RecipeCrucible(key, result, catalyst, tags);
public static CrucibleRecipe addCrucibleRecipe(String key, ItemStack result, Object catalyst, AspectList tags) {
CrucibleRecipe rc = new CrucibleRecipe(key, result, catalyst, tags);
getCraftingRecipes().add(rc);
return rc;
}
@ -183,11 +222,11 @@ public class ThaumcraftApi {
* @param stack the recipe result
* @return the recipe
*/
public static RecipeCrucible getCrucibleRecipe(ItemStack stack) {
public static CrucibleRecipe getCrucibleRecipe(ItemStack stack) {
for (Object r:getCraftingRecipes()) {
if (r instanceof RecipeCrucible) {
if (((RecipeCrucible)r).recipeOutput.isItemEqual(stack))
return (RecipeCrucible)r;
if (r instanceof CrucibleRecipe) {
if (((CrucibleRecipe)r).recipeOutput.isItemEqual(stack))
return (CrucibleRecipe)r;
}
}
return null;
@ -198,12 +237,13 @@ public class ThaumcraftApi {
* @param stack the item
* @return the thaumcraft recipe key that produces that item.
*/
private static HashMap<ItemStack,Object[]> keyCache = new HashMap<ItemStack,Object[]>();
private static HashMap<int[],Object[]> keyCache = new HashMap<int[],Object[]>();
public static Object[] getCraftingRecipeKey(EntityPlayer player, ItemStack stack) {
if (keyCache.containsKey(stack)) {
if (keyCache.get(stack)==null) return null;
if (ThaumcraftApiHelper.isResearchComplete(player.username, (String)(keyCache.get(stack))[0]))
return keyCache.get(stack);
int[] key = new int[] {stack.itemID,stack.getItemDamage()};
if (keyCache.containsKey(key)) {
if (keyCache.get(key)==null) return null;
if (ThaumcraftApiHelper.isResearchComplete(player.username, (String)(keyCache.get(key))[0]))
return keyCache.get(key);
else
return null;
}
@ -212,8 +252,8 @@ public class ThaumcraftApi {
if (ri.getPages()==null) continue;
for (int a=0;a<ri.getPages().length;a++) {
ResearchPage page = ri.getPages()[a];
if (ItemStack.areItemStacksEqual(page.recipeOutput,stack)) {
keyCache.put(stack,new Object[] {ri.key,a});
if (page.recipeOutput!=null && stack !=null && page.recipeOutput.isItemEqual(stack)) {
keyCache.put(key,new Object[] {ri.key,a});
if (ThaumcraftApiHelper.isResearchComplete(player.username, ri.key))
return new Object[] {ri.key,a};
else
@ -222,7 +262,7 @@ public class ThaumcraftApi {
}
}
}
keyCache.put(stack,null);
keyCache.put(key,null);
return null;
}

View File

@ -3,6 +3,7 @@ package thaumcraft.api;
import java.lang.reflect.Method;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import cpw.mods.fml.common.FMLLog;
@ -109,4 +110,28 @@ public class ThaumcraftApiHelper {
}
return null;
}
public static boolean containsMatch(boolean strict, ItemStack[] inputs, ItemStack... targets)
{
for (ItemStack input : inputs)
{
for (ItemStack target : targets)
{
if (itemMatches(target, input, strict))
{
return true;
}
}
}
return false;
}
public static boolean itemMatches(ItemStack target, ItemStack input, boolean strict)
{
if (input == null && target != null || input != null && target == null)
{
return false;
}
return (target.itemID == input.itemID && ((target.getItemDamage() == OreDictionary.WILDCARD_VALUE && !strict) || target.getItemDamage() == input.getItemDamage()));
}
}

View File

@ -1,63 +0,0 @@
package thaumcraft.api;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.tileentity.TileEntity;
/**
*
* @author azanor
*
* Custom tile entity class I use for most of my tile entities. Setup in such a way that only
* the nbt data within readCustomNBT / writeCustomNBT will be sent to the client when the tile
* updates. Apart from all the normal TE data that gets sent that is.
*
*/
public class TileThaumcraft extends TileEntity {
//NBT stuff
@Override
public void readFromNBT(NBTTagCompound nbttagcompound)
{
super.readFromNBT(nbttagcompound);
readCustomNBT(nbttagcompound);
}
public void readCustomNBT(NBTTagCompound nbttagcompound)
{
//TODO
}
@Override
public void writeToNBT(NBTTagCompound nbttagcompound)
{
super.writeToNBT(nbttagcompound);
writeCustomNBT(nbttagcompound);
}
public void writeCustomNBT(NBTTagCompound nbttagcompound)
{
//TODO
}
//Client Packet stuff
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbttagcompound = new NBTTagCompound();
this.writeCustomNBT(nbttagcompound);
return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, -999, nbttagcompound);
}
@Override
public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) {
super.onDataPacket(net, pkt);
this.readCustomNBT(pkt.data);
}
}

View File

@ -133,6 +133,7 @@ public class Aspect {
public void setChatcolor(String chatcolor) {
this.chatcolor = chatcolor;
}
///////////////////////////////
public static LinkedHashMap<String,Aspect> aspects = new LinkedHashMap<String,Aspect>();
@ -146,7 +147,7 @@ public class Aspect {
public static final Aspect ENTROPY = new Aspect("perditio",0x404040,"8",771);
//SECONDARY TODO
public static final Aspect VOID = new Aspect("vacuos",0x888888, new Aspect[] {ORDER, ENTROPY},771);
public static final Aspect VOID = new Aspect("vacuos",0x888888, new Aspect[] {AIR, ENTROPY},771);
public static final Aspect LIGHT = new Aspect("lux",0xfff663, new Aspect[] {AIR, FIRE});
public static final Aspect ENERGY = new Aspect("potentia",0xc0ffff, new Aspect[] {ORDER, FIRE});
public static final Aspect MOTION = new Aspect("motus",0xcdccf4, new Aspect[] {AIR, ORDER});
@ -162,7 +163,7 @@ public class Aspect {
public static final Aspect FLIGHT = new Aspect("volatus",0xe7e7d7, new Aspect[] {AIR, MOTION});
public static final Aspect DARKNESS = new Aspect("tenebrae",0x222222, new Aspect[] {VOID, LIGHT});
public static final Aspect SOUL = new Aspect("spiritus",0xebebfb, new Aspect[] {LIFE, DEATH});
public static final Aspect HEAL = new Aspect("sano",0xff2f34, new Aspect[] {ORDER, LIFE});
public static final Aspect HEAL = new Aspect("sano",0xff2f34, new Aspect[] {LIFE, LIFE});
public static final Aspect TRAVEL = new Aspect("iter",0xe0585b, new Aspect[] {MOTION, EARTH});
public static final Aspect POISON = new Aspect("venenum",0x89f000, new Aspect[] {WATER, DEATH});
@ -190,7 +191,7 @@ public class Aspect {
public static final Aspect MINE = new Aspect("perfodio",0xdcd2d8, new Aspect[] {MAN, STONE});
public static final Aspect TOOL = new Aspect("instrumentum",0x4040ee, new Aspect[] {MAN, METAL});
public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, ENTROPY});
public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, ORDER});
public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, EARTH});
public static final Aspect HUNGER = new Aspect("fames",0x9a0305, new Aspect[] {LIFE, VOID});
public static final Aspect GREED = new Aspect("lucrum",0xe6be44, new Aspect[] {MAN, HUNGER});
public static final Aspect CRAFT = new Aspect("fabrico",0x809d80, new Aspect[] {MAN,TOOL});
@ -198,7 +199,7 @@ public class Aspect {
public static final Aspect CLOTH = new Aspect("pannus",0xeaeac2, new Aspect[] {TOOL, BEAST});
public static final Aspect MECHANISM = new Aspect("machina",0x8080a0, new Aspect[] {MOTION, TOOL});
public static final Aspect TRAP = new Aspect("vinculum",0x9a8080, new Aspect[] {MOTION, ENTROPY});
public static final Aspect EXCHANGE = new Aspect("permutatio",0x578357, new Aspect[] {MOTION, ORDER});
public static final Aspect EXCHANGE = new Aspect("permutatio",0x578357, new Aspect[] {MOTION, WATER});

View File

@ -151,20 +151,15 @@ public class AspectList implements Serializable {
/**
* Reduces the amount of an aspect in this collection by the given amount.
* If reduced below 0 the aspect will be removed completely.
* If the aspect does not exist then a negative value will be added.
* If reduced to 0 or less the aspect will be removed completely.
* @param key
* @param amount
* @return
*/
public AspectList remove(Aspect key, int amount) {
if (getAmount(key)>=amount) {
int am = getAmount(key)-amount;
if (am<=0) aspects.remove(key); else
this.aspects.put(key, am);
} else if (getAmount(key)==0) {
this.aspects.put(key, -amount);
}
int am = getAmount(key)-amount;
if (am<=0) aspects.remove(key); else
this.aspects.put(key, am);
return this;
}
@ -207,6 +202,7 @@ public class AspectList implements Serializable {
if (this.aspects.containsKey(aspect)) {
int oldamount = this.aspects.get(aspect);
if (amount<oldamount) amount=oldamount;
}
this.aspects.put( aspect, amount );
return this;

View File

@ -0,0 +1,64 @@
package thaumcraft.api.aspects;
/**
*
* @author azanor
*
* Used by blocks like the crucible and alembic to hold their aspects.
* Tiles extending this interface will have their aspects show up when viewed by goggles of revealing
*
*/
public interface IAspectContainer {
public AspectList getAspects();
public void setAspects(AspectList aspects);
/**
* This method is used to add a certain amount of an aspect to the tile entity.
* @param tag
* @param amount
* @return the amount of aspect left over that could not be added.
*/
public int addToContainer(Aspect tag, int amount);
/**
* Removes a certain amount of a specific aspect from the tile entity
* @param tag
* @param amount
* @return true if that amount of aspect was available and was removed
*/
public boolean takeFromContainer(Aspect tag, int amount);
/**
* removes a bunch of different aspects and amounts from the tile entity.
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return true if all the aspects and their amounts were available and successfully removed
*/
public boolean takeFromContainer(AspectList ot);
/**
* Checks if the tile entity contains the listed amount (or more) of the aspect
* @param tag
* @param amount
* @return
*/
public boolean doesContainerContainAmount(Aspect tag,int amount);
/**
* Checks if the tile entity contains all the listed aspects and their amounts
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return
*/
public boolean doesContainerContain(AspectList ot);
/**
* Returns how much of the aspect this tile entity contains
* @param tag
* @return the amount of that aspect found
*/
public int containerContains(Aspect tag);
}

View File

@ -5,60 +5,12 @@ package thaumcraft.api.aspects;
/**
* @author Azanor
*
* This interface is implemented by tile entites (or possibly anything else) like jars, alembics and the
* crucible so that they can act as an essentia source for blocks like the infusion altar.
* This interface is implemented by tile entites (or possibly anything else) like jars
* so that they can act as an essentia source for blocks like the infusion altar.
*
*/
public interface IAspectSource {
public interface IAspectSource extends IAspectContainer {
/**
* This method is used to add a certain amount of an aspect to the tile entity.
* @param tag
* @param amount
* @return the amount of aspect left over that could not be added.
*/
public int addToSource(Aspect tag, int amount);
/**
* Removes a certain amount of a specific aspect from the tile entity
* @param tag
* @param amount
* @return true if that amount of aspect was available and was removed
*/
public boolean takeFromSource(Aspect tag, int amount);
/**
* removes a bunch of different aspects and amounts from the tile entity.
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return true if all the aspects and their amounts were available and successfully removed
*/
public boolean takeFromSource(AspectList ot);
/**
* Checks if the tile entity contains the listed amount (or more) of the aspect
* @param tag
* @param amount
* @return
*/
public boolean doesSourceContainAmount(Aspect tag,int amount);
/**
* Checks if the tile entity contains all the listed aspects and their amounts
* @param ot the ObjectTags object that contains the aspects and their amounts.
* @return
*/
public boolean doesSourceContain(AspectList ot);
/**
* Returns how much of the aspect this tile entity contains
* @param tag
* @return the amount of that aspect found
*/
public int sourceContains(Aspect tag);
/**
* Returns all the aspects and their amounts that this tile entity contains
* @return
*/
public AspectList getSourceTags();
}

View File

@ -1,6 +1,7 @@
package thaumcraft.api.aspects;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
*
@ -11,7 +12,7 @@ import net.minecraft.item.ItemStack;
* automatically picks up the aspects they contain
*
*/
public interface IAspectContainerItem {
public interface IEssentiaContainerItem {
public AspectList getAspects(ItemStack itemstack);
public void setAspects(ItemStack itemstack, AspectList aspects);
}

View File

@ -4,23 +4,24 @@ import java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class RecipeCrucible {
public class CrucibleRecipe {
public ItemStack recipeOutput;
public Object catalyst;
public AspectList aspects;
public String key;
public RecipeCrucible(String researchKey, ItemStack result, Object catalyst, AspectList tags) {
public CrucibleRecipe(String researchKey, ItemStack result, Object cat, AspectList tags) {
recipeOutput = result;
this.aspects = tags;
this.key = researchKey;
this.catalyst = catalyst;
if (catalyst instanceof String) {
catalyst = OreDictionary.getOres((String) catalyst);
this.catalyst = cat;
if (cat instanceof String) {
this.catalyst = OreDictionary.getOres((String) cat);
}
}
@ -29,7 +30,7 @@ public class RecipeCrucible {
if (catalyst instanceof ItemStack && !cat.isItemEqual((ItemStack) catalyst)) {
return false;
} else if (catalyst instanceof ArrayList && ((ArrayList<ItemStack>)catalyst).size()>0) {
//if (!OreDictionary.containsMatch(true, ((ArrayList<ItemStack>)catalyst).toArray(new ItemStack[]{}), cat)) return false;
if (!ThaumcraftApiHelper.containsMatch(true, ((ArrayList<ItemStack>)catalyst).toArray(new ItemStack[]{}), cat)) return false;
}
if (itags==null) return false;
for (Aspect tag:aspects.getAspects()) {

View File

@ -0,0 +1,108 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.aspects.AspectList;
public class InfusionRecipe
{
public AspectList aspects;
public String research;
public ItemStack[] components;
public ItemStack recipeInput;
public Object recipeOutput;
public int instability;
public InfusionRecipe(String research, Object output, int inst,
AspectList aspects2, ItemStack input, ItemStack[] recipe) {
this.research = research;
this.recipeOutput = output;
this.recipeInput = input;
this.aspects = aspects2;
this.components = recipe;
this.instability = inst;
}
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
public boolean matches(ArrayList<ItemStack> input, ItemStack central, World world, EntityPlayer player) {
if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, research)) {
return false;
}
ItemStack i2 = central.copy();
if (recipeInput.getItemDamage()==OreDictionary.WILDCARD_VALUE) {
i2.setItemDamage(OreDictionary.WILDCARD_VALUE);
}
if (!areItemStacksEqual(i2, recipeInput, true)) return false;
ArrayList<ItemStack> ii = new ArrayList<ItemStack>();
for (ItemStack is:input) {
ii.add(is.copy());
}
for (ItemStack comp:components) {
boolean b=false;
for (int a=0;a<ii.size();a++) {
i2 = ii.get(a).copy();
if (comp.getItemDamage()==OreDictionary.WILDCARD_VALUE) {
i2.setItemDamage(OreDictionary.WILDCARD_VALUE);
}
if (areItemStacksEqual(i2, comp,true)) {
ii.remove(a);
b=true;
break;
}
}
if (!b) return false;
}
// System.out.println(ii.size());
return ii.size()==0?true:false;
}
private boolean areItemStacksEqual(ItemStack stack0, ItemStack stack1, boolean fuzzy)
{
if (stack0==null && stack1!=null) return false;
if (stack0!=null && stack1==null) return false;
if (stack0==null && stack1==null) return true;
boolean t1=false;
if (fuzzy) {
t1=true;
int od = OreDictionary.getOreID(stack0);
if (od!=-1) {
ItemStack[] ores = OreDictionary.getOres(od).toArray(new ItemStack[]{});
if (ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{stack1}, ores))
return true;
}
}
else
t1=ItemStack.areItemStackTagsEqual(stack0, stack1);
return stack0.itemID != stack1.itemID ? false : (stack0.getItemDamage() != stack1.getItemDamage() ? false : (stack0.stackSize > stack0.getMaxStackSize() ? false : t1));
}
public Object getRecipeOutput() {
return recipeOutput;
}
public AspectList getAspects() {
return aspects;
}
public String getResearch() {
return research;
}
}

View File

@ -6,6 +6,7 @@ import java.util.HashMap;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;

View File

@ -0,0 +1,49 @@
package thaumcraft.api.nodes;
import thaumcraft.api.aspects.IAspectContainer;
public interface INode extends IAspectContainer {
/**
* Unique identifier to distinguish nodes. Normal node id's are based on world id and coordinates
* @return
*/
public String getId();
/**
* Return the type of node
* @return
*/
public NodeType getNodeType();
/**
* Set the type of node
* @return
*/
public void setNodeType(NodeType nodeType);
/**
* Return the node modifier
* @return
*/
public void setNodeModifier(NodeModifier nodeModifier);
/**
* Set the node modifier
* @return
*/
public NodeModifier getNodeModifier();
/**
* Return the maximum capacity of each aspect the node can hold
* @return
*/
public int getNodeVisBase();
/**
* Set the maximum capacity of each aspect the node can hold
* @return
*/
public void setNodeVisBase(short nodeVisBase);
}

View File

@ -0,0 +1,12 @@
package thaumcraft.api.nodes;
/**
*
* @author Azanor
*
* Equipped head slot items that extend this class will make nodes visible in world.
*
*/
public interface IRevealer {
}

View File

@ -0,0 +1,6 @@
package thaumcraft.api.nodes;
public enum NodeModifier
{
BRIGHT, PALE, FADING
}

View File

@ -0,0 +1,6 @@
package thaumcraft.api.nodes;
public enum NodeType
{
NORMAL, UNSTABLE, DARK, TAINTED, HUNGRY, PURE
}

View File

@ -1,218 +0,0 @@
package thaumcraft.api.nodes;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.nbt.NBTTagCompound;
import thaumcraft.api.TileThaumcraft;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
/**
*
* @author azanor
*
* Used as a base for all node tile entities. All the work actually gets done in a non-api TE
* that extends this class.
*
*/
public class TileNodeBase extends TileThaumcraft {
public static enum NodeType
{
NORMAL, UNSTABLE, DARK, TAINTED, HUNGRY, PURE
}
public static enum NodeModifier
{
BRIGHT, PALE, FADING
}
short nodeVisBase = 0;
AspectList aspects = new AspectList();
public static HashMap<String,ArrayList<Integer>> locations = new HashMap<String,ArrayList<Integer>>();
private NodeType nodeType=NodeType.NORMAL;
private NodeModifier nodeModifier=null;
protected String id;
public String getId() {
if (id==null) {
id = generateIdentifier();
}
return id;
}
public String generateIdentifier() {
id = worldObj.provider.dimensionId + ":" + xCoord + ":" + yCoord+ ":" + zCoord;
if (worldObj!=null && locations!=null) {
ArrayList<Integer> t = new ArrayList<Integer>();
t.add(worldObj.provider.dimensionId);
t.add(xCoord);
t.add(yCoord);
t.add(zCoord);
locations.put(id, t);
}
return id;
}
@Override
public void onChunkUnload() {
if (locations!=null) locations.remove(id);
super.onChunkUnload();
}
@Override
public void validate() {
super.validate();
if (id==null) generateIdentifier();
}
/**
* Returns all the aspects and their amounts that this node contains
* @return
*/
public AspectList getAspects() {
return aspects;
}
/**
* Sets the aspects contained within this node
* @return
*/
public void setAspects(AspectList aspects) {
this.aspects = aspects;
short highest=0;
for (Aspect aspect:aspects.getAspects()) {
if (aspects.getAmount(aspect)>highest)
highest=(short) aspects.getAmount(aspect);
}
nodeVisBase = highest;
}
/**
* This method is used to add a certain amount of an aspect to the node.
* @param tag
* @param amount
* @return the amount of aspect left over that could not be added.
*/
public int addToSource(Aspect aspect, int amount) {
int left = (amount+aspects.getAmount(aspect))-nodeVisBase;
left = left>0?left:0;
aspects.add(aspect, amount-left);
return left;
}
/**
* Removes a certain amount of a specific aspect from the node
* @param tag
* @param amount
* @return true if that amount of aspect was available and was removed
*/
public boolean takeFromSource(Aspect aspect, int amount) {
return aspects.reduce(aspect, amount);
}
/**
* Removes a single random aspect from the source
* @return the aspect that was retrieved (it is assumed that only 1 of that aspect has been removed).
* Should return null if there are not enough aspects.
*/
public Aspect takeRandomPrimalFromSource() {
Aspect[] primals = aspects.getPrimalAspects();
Aspect asp = primals[worldObj.rand.nextInt(primals.length)];
if (asp !=null && aspects.reduce(asp,1)) {
return asp;
} else {
return null;
}
}
public Aspect chooseRandomFilteredFromSource(AspectList filter) {
ArrayList<Aspect> validaspects = new ArrayList<Aspect>();
for (Aspect prim:aspects.getAspects()) {
if (filter.getAmount(prim)>0 && aspects.getAmount(prim)>0) validaspects.add(prim);
}
if (validaspects.size()==0) return null;
Aspect asp = validaspects.get(worldObj.rand.nextInt(validaspects.size()));
if (asp !=null && aspects.getAmount(asp)>0) {
return asp;
} else {
return null;
}
}
@Override
public void readCustomNBT(NBTTagCompound nbttagcompound)
{
this.id = nbttagcompound.getString("nodeId");
this.nodeVisBase = nbttagcompound.getShort("nodeVisBase");
if (worldObj!=null && locations!=null) {
ArrayList<Integer> t = new ArrayList<Integer>();
t.add(worldObj.provider.dimensionId);
t.add(xCoord);
t.add(yCoord);
t.add(zCoord);
locations.put(id, t);
}
this.setNodeType(NodeType.values()[nbttagcompound.getByte("type")]);
byte mod = nbttagcompound.getByte("modifier");
if (mod>=0)
this.setNodeModifier(NodeModifier.values()[mod]);
else
this.setNodeModifier(null);
aspects.readFromNBT(nbttagcompound);
}
@Override
public void writeCustomNBT(NBTTagCompound nbttagcompound)
{
if (id==null) id = generateIdentifier();
nbttagcompound.setString("nodeId", id);
nbttagcompound.setShort("nodeVisBase", nodeVisBase);
nbttagcompound.setByte("type", (byte) this.getNodeType().ordinal());
nbttagcompound.setByte("modifier", getNodeModifier()==null?-1:(byte) this.getNodeModifier().ordinal());
aspects.writeToNBT(nbttagcompound);
}
public NodeType getNodeType() {
return nodeType;
}
public void setNodeType(NodeType nodeType) {
this.nodeType = nodeType;
}
public void setNodeModifier(NodeModifier nodeModifier) {
this.nodeModifier = nodeModifier;
}
public NodeModifier getNodeModifier() {
return nodeModifier;
}
public int getNodeVisBase() {
return nodeVisBase;
}
public void setNodeVisBase(short nodeVisBase) {
this.nodeVisBase = nodeVisBase;
}
public void nodeChange() {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
}

View File

@ -7,8 +7,9 @@ import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.crafting.CrucibleRecipe;
import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.api.crafting.RecipeCrucible;
import thaumcraft.api.crafting.InfusionRecipe;
public class ResearchPage {
public static enum PageType
@ -20,6 +21,7 @@ public class ResearchPage {
ARCANE_CRAFTING,
ASPECTS,
NORMAL_CRAFTING,
INFUSION_CRAFTING,
COMPOUND_CRAFTING
}
@ -60,12 +62,27 @@ public class ResearchPage {
}
/**
* @param recipe a vanilla crafting recipe.
* @param recipe a collection of vanilla crafting recipes.
*/
public ResearchPage(IRecipe[] recipe) {
this.type = PageType.NORMAL_CRAFTING;
this.recipe = recipe;
// this.recipeOutput = recipe.getRecipeOutput();
}
/**
* @param recipe a collection of arcane crafting recipes.
*/
public ResearchPage(IArcaneRecipe[] recipe) {
this.type = PageType.ARCANE_CRAFTING;
this.recipe = recipe;
}
/**
* @param recipe a collection of infusion crafting recipes.
*/
public ResearchPage(InfusionRecipe[] recipe) {
this.type = PageType.INFUSION_CRAFTING;
this.recipe = recipe;
}
/**
@ -88,12 +105,25 @@ public class ResearchPage {
/**
* @param recipe an alchemy crafting recipe.
*/
public ResearchPage(RecipeCrucible recipe) {
public ResearchPage(CrucibleRecipe recipe) {
this.type = PageType.CRUCIBLE_CRAFTING;
this.recipe = recipe;
this.recipeOutput = recipe.recipeOutput;
}
/**
* @param recipe an infusion crafting recipe.
*/
public ResearchPage(InfusionRecipe recipe) {
this.type = PageType.INFUSION_CRAFTING;
this.recipe = recipe;
if (recipe.recipeOutput instanceof ItemStack) {
this.recipeOutput = (ItemStack) recipe.recipeOutput;
} else {
this.recipeOutput = recipe.recipeInput;
}
}
/**
* @param image
* @param caption this can (but does not have to) be a reference to a localization variable, not the actual text.

View File

@ -14,7 +14,15 @@ public interface IWandFocus {
WAVE, CHARGE;
}
/**
* @return The color the focus should be changed to.
*/
public int getFocusColor();
/**
* @return An icon that will be drawn as a block inside the focus "block".
*/
Icon getFocusDepthLayerIcon();
public Icon getOrnament();
@ -47,6 +55,10 @@ public interface IWandFocus {
boolean onFocusBlockStartBreak(ItemStack itemstack, int x, int y, int z, EntityPlayer player);
public boolean acceptsEnchant(int id);
}

View File

@ -2,7 +2,9 @@ package thaumcraft.api.wands;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
@ -11,6 +13,7 @@ import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import thaumcraft.api.ThaumcraftApi;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import cpw.mods.fml.relauncher.Side;
@ -33,6 +36,12 @@ public class ItemFocusBasic extends Item implements IWandFocus {
return icon;
}
@Override
public boolean isItemTool(ItemStack par1ItemStack)
{
return true;
}
@Override
public void addInformation(ItemStack stack,EntityPlayer player, List list, boolean par4) {
AspectList al = this.getVisCost();
@ -96,7 +105,12 @@ public class ItemFocusBasic extends Item implements IWandFocus {
*/
@Override
public String getSortingHelper(ItemStack itemstack) {
return "00";
Map<Integer,Integer> ench = EnchantmentHelper.getEnchantments(itemstack);
String out="";
for (Integer lvl:ench.values()) {
out = out + lvl + "";
}
return out;
}
@Override
@ -122,6 +136,23 @@ public class ItemFocusBasic extends Item implements IWandFocus {
return WandFocusAnimation.WAVE;
}
@Override
public Icon getFocusDepthLayerIcon() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see thaumcraft.api.wands.IWandFocus#acceptsEnchant(int)
* By default fortune is off for all wands
*/
@Override
public boolean acceptsEnchant(int id) {
if (id==ThaumcraftApi.enchantFrugal||
id==ThaumcraftApi.enchantPotency) return true;
return false;
}

View File

@ -58,10 +58,10 @@ public class WandTriggerRegistry {
*/
public static boolean performTrigger(World world, ItemStack wand, EntityPlayer player,
int x, int y, int z, int side, int blockid, int meta) {
if (!triggers.containsKey(Arrays.asList(blockid,meta))) return false;
List l = triggers.get(Arrays.asList(blockid,meta));
if (l==null) l = triggers.get(Arrays.asList(blockid,-1));
if (l==null) return false;
IWandTriggerManager manager = (IWandTriggerManager) l.get(0);
int event = (Integer) l.get(1);