Added the Thaumcraft API, started Thaumcraft integration and created a way of referencing BOP blocks easily

This commit is contained in:
Adubbz 2013-04-24 13:13:22 +10:00
parent 9b237e283c
commit 10326d1396
30 changed files with 3031 additions and 1 deletions

View File

@ -10,6 +10,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import biomesoplenty.api.BlockReferences;
import biomesoplenty.configuration.BOPBiomes;
import biomesoplenty.configuration.BOPBlocks;
import biomesoplenty.configuration.BOPConfiguration;

View File

@ -0,0 +1,72 @@
package biomesoplenty.api;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import com.google.common.base.Optional;
public class BlockReferences {
public static enum EnumBlocks
{
acaciaLog (Blocks.logs1, 0),
cherryLog (Blocks.logs1, 1),
darkLog (Blocks.logs1, 2),
firLog (Blocks.logs2, 3),
holyLog (Blocks.logs1, 0),
magicLog (Blocks.logs2, 1),
mangroveLog (Blocks.logs2, 2),
palmLog (Blocks.logs2, 3),
redwoodLog (Blocks.logs3, 0),
willowLog (Blocks.logs3, 1),
deadLog (Blocks.logs3, 2),
bigFlowerStem (Blocks.logs3, 3),
;
public Optional<? extends Block> block;
public int meta;
private EnumBlocks(Optional<? extends Block> block, int meta) {
this.block = block;
this.meta = meta;
}
public Optional<? extends Block> getBlock() {
return block;
}
public int getMeta() {
return meta;
}
}
public static ItemStack getBlockItemStack(String string)
{
Optional<? extends Block> stackblock = EnumBlocks.valueOf(string).block;
int stackmeta = EnumBlocks.valueOf(string).meta;
if (stackmeta != 0)
{
return new ItemStack(stackblock.get(), 1, stackmeta);
}
else
{
return new ItemStack(stackblock.get(), 1);
}
}
public static int getBlockID(String string)
{
Optional<? extends Block> stackblock = EnumBlocks.valueOf(string).block;
return stackblock.get().blockID;
}
public static int getBlockMeta(String string)
{
int stackmeta = EnumBlocks.valueOf(string).meta;
return stackmeta;
}
}

View File

@ -1,6 +1,5 @@
package biomesoplenty.api;
public class Entities {
public static Class Mudball = getClass("biomesoplenty.items.projectiles.EntityMudball");

View File

@ -101,6 +101,7 @@ public class BOPConfiguration {
public static boolean swamplandGen;
public static boolean jungleGen;
//Block IDS
public static int mudID;
public static int driedDirtID;
public static int redRockID;
@ -170,6 +171,7 @@ public class BOPConfiguration {
public static int colourizedLeavesID;
//Item IDs
public static int shroomPowderID;
public static int ancientStaffID;
@ -201,6 +203,7 @@ public class BOPConfiguration {
public static int leggingsAmethystID;
public static int bootsAmethystID;
//Biome IDS
public static int alpsID;
public static int arcticID;
public static int arcticForestID;

View File

@ -38,5 +38,16 @@ public class BOPCrossIntegration {
e.printStackTrace(System.err);
}
}
if (Loader.isModLoaded("Thaumcraft"))
{
try {
ThaumcraftIntegration.init();
}
catch (Exception e) {
System.out.println("[BiomesOPlenty] There was an error while integrating Thaumcraft with Biomes O' Plenty!");
e.printStackTrace(System.err);
}
}
}
}

View File

@ -0,0 +1,168 @@
package biomesoplenty.integration;
import net.minecraft.item.ItemStack;
import biomesoplenty.api.BlockReferences;
import biomesoplenty.api.Blocks;
import biomesoplenty.api.BlockReferences.EnumBlocks;
import thaumcraft.api.EnumTag;
import thaumcraft.api.ObjectTags;
import thaumcraft.api.ThaumcraftApi;
public class ThaumcraftIntegration {
protected static void init()
{
addAspects();
}
private static void addAspects()
{
//TODO: Ensure all tags are balanced (Logs shouldn't give more light when turned into planks)
//Woods
ThaumcraftApi.registerObjectTag(getBID("acaciaLog"), getBMeta("acaciaLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("cherryLog"), getBMeta("cherryLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("darkLog"), getBMeta("darkLog"), (new ObjectTags()).add(EnumTag.WOOD, 8).add(EnumTag.DARK, 2));
ThaumcraftApi.registerObjectTag(getBID("firLog"), getBMeta("firLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("holyLog"), getBMeta("holyLog"), (new ObjectTags()).add(EnumTag.WOOD, 8).add(EnumTag.LIGHT, 2));
ThaumcraftApi.registerObjectTag(getBID("magicLog"), getBMeta("magicLog"), (new ObjectTags()).add(EnumTag.WOOD, 8).add(EnumTag.MAGIC, 2));
ThaumcraftApi.registerObjectTag(getBID("mangroveLog"), getBMeta("mangroveLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("palmLog"), getBMeta("palmLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("redwoodLog"), getBMeta("redwoodLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("willowLog"), getBMeta("willowLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("deadLog"), getBMeta("deadLog"), (new ObjectTags()).add(EnumTag.WOOD, 8));
ThaumcraftApi.registerObjectTag(getBID("bigFlowerStem"), getBMeta("bigFlowerStem"), (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.MAGIC, 1));
//Planks
/*ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 0, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 1, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 2, (new ObjectTags()).add(EnumTag.WOOD, 2).add(EnumTag.DARK, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 3, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 4, (new ObjectTags()).add(EnumTag.WOOD, 2).add(EnumTag.LIGHT, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 5, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 6, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 7, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 8, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 9, (new ObjectTags()).add(EnumTag.WOOD, 2));
ThaumcraftApi.registerObjectTag(Blocks.planks.get().blockID, 10, (new ObjectTags()).add(EnumTag.WOOD, 2));
//Leaves
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.holyLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.LIGHT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.blueLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.MAGIC, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.darkLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.DARK, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.deadLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.DEATH, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.appleLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.LIFE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.acaciaLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.firLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mangroveLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.palmLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redwoodLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.willowLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.autumnLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.orangeLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.pinkLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.whiteLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bambooLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.originLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.appleLeavesFruitless.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redLeaves.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
//Saplings
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.holySapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2).add(EnumTag.LIGHT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.magicSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2).add(EnumTag.MAGIC, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.darkSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2).add(EnumTag.DARK, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.brownSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2).add(EnumTag.DEATH, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.acaciaSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.firSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mangroveSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.palmSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redwoodSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.willowSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.orangeSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.pinkSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.whiteSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.appleSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.originSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.yellowSapling.blockID, -1, (new ObjectTags()).add(EnumTag.WOOD, 4).add(EnumTag.PLANT, 2));
//Blocks
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mud.blockID, -1, (new ObjectTags()).add(EnumTag.WATER, 3).add(EnumTag.EARTH, 6));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.driedDirt.blockID, -1, (new ObjectTags()).add(EnumTag.DESTRUCTION, 1).add(EnumTag.EARTH, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redRock.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.ash.blockID, -1, (new ObjectTags()).add(EnumTag.DESTRUCTION, 3).add(EnumTag.EXCHANGE, 3));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.ashStone.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.EXCHANGE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.hardIce.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 2).add(EnumTag.COLD, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.originGrass.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.EARTH, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.hardSand.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.EARTH, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.hardDirt.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.EARTH, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.holyGrass.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.EARTH, 2).add(EnumTag.LIGHT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.holyStone.blockID, -1, (new ObjectTags()).add(EnumTag.LIGHT, 1).add(EnumTag.ROCK, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.cragRock.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.quicksand.blockID, -1, (new ObjectTags()).add(EnumTag.EARTH, 2).add(EnumTag.TRAP, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.smolderingGrass.blockID, -1, (new ObjectTags()).add(EnumTag.EARTH, 2).add(EnumTag.FIRE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bambooThatching.blockID, -1, (new ObjectTags()).add(EnumTag.WATER, 14).add(EnumTag.PLANT, 14));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.amethystBlock.blockID, -1, (new ObjectTags()).add(EnumTag.VALUABLE, 58).add(EnumTag.PURE, 58).add(EnumTag.CRYSTAL, 87));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.amethystOre.blockID, -1, (new ObjectTags()).add(EnumTag.VALUABLE, 6).add(EnumTag.PURE, 6).add(EnumTag.CRYSTAL, 14).add(EnumTag.ROCK, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.redRockCobble.blockID, -1, (new ObjectTags()).add(EnumTag.DESTRUCTION, 1).add(EnumTag.ROCK, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.giantFlowerRed.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.MAGIC, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.giantFlowerStem.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.MAGIC, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.giantFlowerYellow.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.MAGIC, 1));
//Items
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.amethyst.itemID, -1, (new ObjectTags()).add(EnumTag.VALUABLE, 8).add(EnumTag.PURE, 8).add(EnumTag.CRYSTAL, 16));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.barleyItem.itemID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.LIFE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.ashes.itemID, -1, (new ObjectTags()).add(EnumTag.DESTRUCTION, 1).add(EnumTag.EXCHANGE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.cattailItem.itemID, -1, (new ObjectTags()).add(EnumTag.WATER, 1).add(EnumTag.PLANT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bambooItem.itemID, -1, (new ObjectTags()).add(EnumTag.WATER, 2).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mudBrick.itemID, -1, (new ObjectTags()).add(EnumTag.EARTH, 2).add(EnumTag.FIRE, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mudBall.itemID, -1, (new ObjectTags()).add(EnumTag.WATER, 1).add(EnumTag.EARTH, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.shroomPowder.itemID, -1, (new ObjectTags()).add(EnumTag.FUNGUS, 2).add(EnumTag.DESTRUCTION, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bopDisc.itemID, -1, (new ObjectTags()).add(EnumTag.SOUND, 12).add(EnumTag.VALUABLE, 4).add(EnumTag.CROP, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bopDiscMud.itemID, -1, (new ObjectTags()).add(EnumTag.SOUND, 12).add(EnumTag.VALUABLE, 4).add(EnumTag.EARTH, 2).add(EnumTag.WATER, 2));
//Plants
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.toadstool.blockID, -1, (new ObjectTags()).add(EnumTag.FUNGUS, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.tinyCactus.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2).add(EnumTag.WEAPON, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.holyTallGrass.blockID, -1, (new ObjectTags()).add(EnumTag.WIND, 1).add(EnumTag.PLANT, 1).add(EnumTag.LIGHT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.desertSprouts.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.duneGrass.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1).add(EnumTag.WIND, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.thorn.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2).add(EnumTag.WEAPON, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.desertGrass.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.deadGrass.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.treeMoss.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.moss.blockID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.sproutItem.itemID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.bushItem.itemID, -1, (new ObjectTags()).add(EnumTag.PLANT, 2));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.mediumGrassItem.itemID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.shortGrassItem.itemID, -1, (new ObjectTags()).add(EnumTag.PLANT, 1));
//Flowers
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.violet.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.hydrangea.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.deathbloom.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.DEATH, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.glowFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4).add(EnumTag.LIGHT, 1));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.whiteFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.blueFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.purpleFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.orangeFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.pinkFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 4));
ThaumcraftApi.registerObjectTag(mod_BiomesOPlenty.tinyFlower.blockID, -1, (new ObjectTags()).add(EnumTag.FLOWER, 1).add(EnumTag.PLANT, 1));*/
}
private static int getBID(String name) {
return BlockReferences.getBlockID(name);
}
private static int getBMeta(String name) {
return BlockReferences.getBlockMeta(name);
}
}

View File

@ -0,0 +1,106 @@
package thaumcraft.api;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
public enum EnumTag {
UNKNOWN (63,"Obscurus","Unknown, Obscured",1,false,0x282828),
WIND (0,"Aura","Air, Wind, Breath, Movement",1,false,0xc0c0d7),
FIRE (6,"Ignis","Fire, Heat, Burn, Light",2,true,0xff5a01),
ROCK (11,"Saxum","Earth, Stone, Ground, Foundation",4,false,0x5c4842),
WATER (21,"Aqua","Water, Fluid, Cold",3,false,0x3cd4fc),
PLANT (36,"Herba","Herb, Plant, Grass",4,false,0x01ac00),
BEAST (53,"Bestia","Animal, Beast",3,true,0x9f6409),
FLESH (54,"Corpus","Body, Flesh, Physique",3,false,0xee478d),
METAL (12,"Metallum","Metal, Mine, Ore",4,false,0xd8d8d8),
CRYSTAL (20,"Vitreus","Glass, Crystal, Gem, Transparent",1,false,0x80ffff),
SOUND (24,"Sonus","Sound, Noise, Din",3,false,0x10c9c0),
EXCHANGE (14,"Permutatio","Exchange, Change, Barter",4,false,0x578357),
LIFE (26,"Victus","Life force, Food, Sustenance",3,false,0xde0005),
DEATH (27,"Mortuus","Death, Decay, Undead",6,true,0x404040),
SPIRIT (30,"Animus","Soul, Spirit",1,false,0xe0e0e0),
VOID (2,"Vacuos","Empty, Void, Insubstantial",1,true,0xc0c0d7),
VISION (3,"Visum","Sight, Vision, Appearance",3,false,0xd5d4ec),
KNOWLEDGE (4,"Cognitio","Learning, Knowledge, Inquiry",1,false,0x8080ee),
DESTRUCTION (7,"Fractus","Destruction, Fragmented, Shattered",2,true,0x506050),
POWER (9,"Potentia","Power, Energy, Strength",2,true,0xc0ffff),
MECHANISM (10,"Machina","Mechanism, Machine, Device",2,false,0x8080a0),
ARMOR (17,"Tutamen","Defense, Protection, Security",4,false,0x00c0c0),
WEAPON (18,"Telum","Arrow, Sword, Weapon",2,true,0xc05050),
TOOL (19,"Instrumentum","Instrument, Tool, Implement",4,false,0x4040ee),
POISON (29,"Venenum","Poison, Drug, Impure",3,true,0x89f000),
VALUABLE (31,"Carus","Expensive, Precious, Valuable",4,false,0xe6be44),
PURE (37,"Purus","Pure, Clean, Stainless",3,false,0xa5fffd),
MAGIC (40,"Praecantatio","Magic, Sorcery",5,false,0x9700c0),
TIME (41,"Tempus","Time, Moment, Season",5,false,0x9070e0),
CONTROL (48,"Imperito","Control, Command, Dominate",5,false,0x98994b),
DARK (49,"Tenebris","Dark, Night, Blindness",5,true,0x252525),
CRAFT (50,"Fabrico","Create, Construct, Work",2,false,0x809d80),
EVIL (56,"Malum","Evil, The Nether, Malice",5,true,0x700000),
FLUX (57,"Mutatio","Flux, Chaos",5,true,0xb80bb9),
ELDRITCH (58,"Alienis","Eldritch, The End, Strange, Alien",5,true,0x805080),
//TOREMOVE
TRAP (28,"Vinculum","Bind, Imprison, Trap",4,true,0x9a8080),
INSECT (55,"Bestiola","Spider, Web, Insects",3,false,0x808880),
MOTION (1,"Motus","Motion, Movement, Speed",1,false,0xcdccf4),
FLIGHT (5,"Volito","Flight, Leap",1,false,0xe7e7d7),
LIGHT (8,"Lux","Light, Brightness, Day",2,false,0xfff663),
CLOTH (15,"Pannus","Cloth, Fabric, Garment, Thread",3,false,0xeaeac2),
EARTH (16,"Solum","Earth, Soil, Ground, Foundation",4,false,0x713f2d),
WEATHER (22,"Aer","Weather, Mist, Climate",3,false,0xc0ffff),
COLD (23,"Gelum","Cold, Ice, Frost",3,true,0xe1ffff),
HEAL (25,"Sano","Heal, Repair, Make Sound",3,false, 0xff8184),
WOOD (32,"Lignum","Wood, Forest, Tree",4,false,0x058105),
FLOWER (33,"Flos","Flower, Bloom, Blossom",4,false,0xffff40),
FUNGUS (34,"Fungus","Mushroom, Toadstool, Fungi",4,false,0xf7e5c7),
CROP (35,"Messis","Crops, Harvest",4,false,0xe3ff80),
;
// Attributes
public final int id;
public final String name;
public final String meaning;
/**
* rough categories for the aspect types. Mostly just used to determine the common aspect type in certain biomes.
*/
public final int element; //1-air, 2-fire, 3-water, 4-earth, 5-mystical, 6-dead/aggressive, 999-deprecated
/**
* will wisps spawned from this fluxtype be aggressive?
*/
public final boolean aggro;
public final int color;
private EnumTag(int id, String name, String meaning, int element,boolean aggro, int color ) {
this.id = id;
this.name = name;
this.meaning = meaning;
this.element = element;
this.color = color;
this.aggro = aggro;
}
// Lookup
private static final Map<Integer,EnumTag> lookup = new HashMap<Integer,EnumTag>();
static { for(EnumTag s : EnumSet.allOf(EnumTag.class)) lookup.put(s.getId(), s); }
public int getId() { return id; }
public static EnumTag get(int id) {
if (lookup.get(id)==null||lookup.get(id).element==999)
return EnumTag.FLUX;
else
return lookup.get(id);
}
}

View File

@ -0,0 +1,63 @@
package thaumcraft.api;
/**
* @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.
*
*/
public interface IAspectSource {
/**
* 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(EnumTag 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(EnumTag 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(ObjectTags ot);
/**
* Checks if the tile entity contains the listed amount (or more) of the aspect
* @param tag
* @param amount
* @return
*/
public boolean doesSourceContainAmount(EnumTag 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(ObjectTags ot);
/**
* Returns how much of the aspect this tile entity contains
* @param tag
* @return the amount of that aspect found
*/
public int sourceContains(EnumTag tag);
/**
* Returns all the aspects and their amounts that this tile entity contains
* @return
*/
public ObjectTags getSourceTags();
}

View File

@ -0,0 +1,15 @@
package thaumcraft.api;
/**
* @author Azanor
* ItemArmor with this interface will grant a discount to the vis cost of actions the wearer performs with casting wands.
* The amount returned is the percentage by which the cost is discounted. There is a built-int max discount of 50%, but
* individual items really shouldn't have a discount more than 5%
*/
public interface IVisDiscounter {
int getVisDiscount();
}

View File

@ -0,0 +1,27 @@
package thaumcraft.api;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
/**
* @author Azanor
* Items and tools with this interface can receive the Repair enchantment.
* Armor, weapons and tools are handled automatically.
* Usually 1 vis equals 1 point of durability every 2 seconds (1 second for repair II)
* Repair enchant values over II also grants a reduction in speed, but at a much
* reduced rate (about 2 ticks per rating over II)
* Some sample code:<p>
* <i>
* public void doRepair(ItemStack is, Entity e) {<br>
* if (AuraManager.decreaseClosestAura(e.worldObj,e.posX, e.posY, e.posZ, 1)) {<br>
* is.damageItem(-1,(EntityLiving) e);<br>
* }<br>
* }<br><br>
*</i>
*/
public interface IVisRepairable {
void doRepair(ItemStack stack, Entity e);
}

View File

@ -0,0 +1,58 @@
package thaumcraft.api;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.FMLLog;
/**
* @author Azanor
*
* This is used to gain access to the items in my mod.
* I only give some examples and it will probably still
* require a bit of work for you to get hold of everything you need.
*
*/
public class ItemApi {
public static ItemStack getItem(String itemString, int meta) {
ItemStack item = null;
try {
String itemClass = "thaumcraft.common.Config";
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) {
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);
}
return item;
}
/**
*
* Some examples
*
* Casting Wands:
* itemWandCastingApprentice, itemWandCastingAdept, itemWandCastingMage
*
* Elemental Wands:
* itemWandFire, itemWandLightning, itemWandFrost, itemWandTrade, itemWandExcavation, itemHellrod
*
* Resources:
* itemEssence, itemWispEssence, itemResource, itemShard, itemNugget,
* itemNuggetChicken, itemNuggetBeef, itemNuggetPork, itemTripleMeatTreat,
* blockWooden, blockMarker
*
* Research:
* itemResearchNotes, itemInkwell, itemThaumonomicon
*
*/
}

View File

@ -0,0 +1,171 @@
package thaumcraft.api;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.item.ItemStack;
public class ObjectTags implements Serializable {
public Map<EnumTag,Integer> tags = new HashMap<EnumTag,Integer>();//aspects associated with this object
/**
* this creates a new aspect list with preloaded values based off the aspects of the given item.
* @param id the item/block id of an existing item
* @param meta the damage value of an existing item
*/
public ObjectTags(int id, int meta) {
ObjectTags temp = ThaumcraftApiHelper.getObjectTags(new ItemStack(id,1,meta));
if (temp!=null)
for (EnumTag tag:temp.getAspects()) {
add(tag,temp.getAmount(tag));
}
}
public ObjectTags() {
}
/**
* @return the amount of different aspects in this collection
*/
public int size() {
return tags.size();
}
/**
* @return an array of all the aspects in this collection
*/
public EnumTag[] getAspects() {
EnumTag[] q = new EnumTag[1];
return tags.keySet().toArray(q);
}
/**
* @return an array of all the aspects in this collection sorted by name
*/
public EnumTag[] getAspectsSorted() {
EnumTag[] out = tags.keySet().toArray(new EnumTag[1]);
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
EnumTag e1 = out[a];
EnumTag e2 = out[a+1];
if (e1!=null && e2!=null && e1.name.compareTo(e2.name)>0) {
out[a] = e2;
out[a+1] = e1;
change = true;
break;
}
}
} while (change==true);
return out;
}
/**
* @return an array of all the aspects in this collection sorted by name
*/
public EnumTag[] getAspectsSortedAmount() {
EnumTag[] out = tags.keySet().toArray(new EnumTag[1]);
boolean change=false;
do {
change=false;
for(int a=0;a<out.length-1;a++) {
int e1 = getAmount(out[a]);
int e2 = getAmount(out[a+1]);
if (e1>0 && e2>0 && e2>e1) {
EnumTag ea = out[a];
EnumTag eb = out[a+1];
out[a] = eb;
out[a+1] = ea;
change = true;
break;
}
}
} while (change==true);
return out;
}
/**
* @param key
* @return the amount associated with the given aspect in this collection
*/
public int getAmount(EnumTag key) {
return tags.get(key)==null?0:tags.get(key);
}
/**
* Reduces the amount of an aspect in this collection by the given amount.
* If reduced below 0 the aspect will be removed completely.
* @param key
* @param amount
* @return
*/
public boolean reduceAmount(EnumTag key, int amount) {
if (getAmount(key)>=amount) {
int am = getAmount(key)-amount;
if (am<=0) tags.remove(key); else
tags.put(key, am);
return true;
}
return false;
}
/**
* 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.
* Only used by aura internals for flux management.
* @param key
* @param amount
* @return
*/
public ObjectTags remove(EnumTag key, int amount) {
if (getAmount(key)>=amount) {
int am = getAmount(key)-amount;
if (am<=0) tags.remove(key); else
this.tags.put(key, am);
} else if (getAmount(key)==0) {
this.tags.put(key, -amount);
}
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then its value will be increased by the given amount.
* @param aspect
* @param amount
* @return
*/
public ObjectTags add(EnumTag aspect, int amount) {
if (this.tags.containsKey(aspect)) {
int oldamount = this.tags.get(aspect);
amount+=oldamount;
}
this.tags.put( aspect, amount );
return this;
}
/**
* Adds this aspect and amount to the collection.
* If the aspect exists then only the highest of the old or new amount will be used.
* @param aspect
* @param amount
* @return
*/
public ObjectTags merge(EnumTag aspect, int amount) {
if (this.tags.containsKey(aspect)) {
int oldamount = this.tags.get(aspect);
if (amount<oldamount) amount=oldamount;
}
this.tags.put( aspect, amount );
return this;
}
}

View File

@ -0,0 +1,816 @@
package thaumcraft.api;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.item.EnumArmorMaterial;
import net.minecraft.item.EnumToolMaterial;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumHelper;
import org.w3c.dom.Document;
import thaumcraft.api.aura.AuraNode;
import thaumcraft.api.crafting.IArcaneRecipe;
import thaumcraft.api.crafting.IInfusionRecipe;
import thaumcraft.api.crafting.RecipeCrucible;
import thaumcraft.api.crafting.ShapedArcaneCraftingRecipes;
import thaumcraft.api.crafting.ShapedInfusionCraftingRecipes;
import thaumcraft.api.crafting.ShapelessArcaneCraftingRecipes;
import thaumcraft.api.crafting.ShapelessInfusionCraftingRecipes;
import thaumcraft.api.research.IScanEventHandler;
import thaumcraft.api.research.ResearchList;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInterModComms;
/**
* @author Azanor
*
*
* IMPORTANT: If you are adding your own aspects to items it is a good idea to do it AFTER Thaumcraft adds its aspects, otherwise odd things may happen.
*
*/
public class ThaumcraftApi {
//Materials
public static EnumToolMaterial toolMatThaumium = EnumHelper.addToolMaterial("THAUMIUM", 3, 400, 7F, 2, 22);
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);
//Miscellaneous
/**
* Portable Hole Block-id Blacklist.
* Simply add the block-id's of blocks you don't want the portable hole to go through.
*/
public static ArrayList<Integer> portableHoleBlackList = new ArrayList<Integer>();
//RESEARCH/////////////////////////////////////////
public static Document researchDoc = null;
public static ArrayList<String> apiResearchFiles = new ArrayList<String>();
public static ArrayList<IScanEventHandler> scanEventhandlers = new ArrayList<IScanEventHandler>();
/**
* Used to add your own xml files that the research system will check of recipes and descriptions of custom research
* @param resourceLoc The xml file. For example The default file used by TC is
* "/thaumcraft/resources/research.xml"
*/
public static void registerResearchXML(String resourceLoc) {
if (!apiResearchFiles.contains(resourceLoc)) apiResearchFiles.add(resourceLoc);
}
public static void registerScanEventhandler(IScanEventHandler scanEventHandler) {
scanEventhandlers.add(scanEventHandler);
}
//RECIPES/////////////////////////////////////////
private static ArrayList crucibleRecipes = new ArrayList();
private static List craftingRecipes = new ArrayList();
private static HashMap<List,ItemStack> smeltingBonus = new HashMap<List,ItemStack>();
private static ArrayList<List> smeltingBonusExlusion = new ArrayList<List>();
/**
* This method is used to determine what bonus items are generated when the infernal furnace smelts items
* @param in The result (not input) of the smelting operation. e.g. new ItemStack(ingotGold)
* @param out The bonus item that can be produced from the smelting operation e.g. new ItemStack(nuggetGold,0,0).
* Stacksize should be 0 unless you want to guarantee that at least 1 item is always produced.
*/
public static void addSmeltingBonus(ItemStack in, ItemStack out) {
smeltingBonus.put(
Arrays.asList(in.itemID,in.getItemDamage()),
new ItemStack(out.itemID,0,out.getItemDamage()));
}
/**
* Returns the bonus item produced from a smelting operation in the infernal furnace
* @param in The result of the smelting operation. e.g. new ItemStack(ingotGold)
* @return the The bonus item that can be produced
*/
public static ItemStack getSmeltingBonus(ItemStack in) {
return smeltingBonus.get(Arrays.asList(in.itemID,in.getItemDamage()));
}
/**
* Excludes specific items from producing bonus items when they are smelted in the infernal furnace, even
* if their smelt result would normally produce a bonus item.
* @param in The item to be smelted that should never produce a bonus item (e.g. the various macerated dusts form IC2)
* Even though they produce gold, iron, etc. ingots, they should NOT produce bonus nuggets as well.
*/
public static void addSmeltingBonusExclusion(ItemStack in) {
smeltingBonusExlusion.add(Arrays.asList(in.itemID,in.getItemDamage()));
}
/**
* Sees if an item is allowed to produce bonus items when smelted in the infernal furnace
* @param in The item you wish to check
* @return true or false
*/
public static boolean isSmeltingBonusExluded(ItemStack in) {
return smeltingBonusExlusion.contains(Arrays.asList(in.itemID,in.getItemDamage()));
}
public static List getCraftingRecipes() {
return craftingRecipes;
}
/**
* NOTE:
* All arcane and infusion crafting recipes are NBT sensitive.
* Simply add as much nbt data to the crafting ingredient itemstacks as you wish
* to match with the actual input items. For example this recipe will turn a warded
* jar filled with crystal essentia into a stack of diamonds:
*
* ItemStack is = new ItemStack(itemJarFilled);
* is.setTagInfo("tag", new NBTTagByte("tag", (byte) EnumTag.CRYSTAL.id));
* is.setTagInfo("amount", new NBTTagByte("amount", (byte) 64));
* ThaumcraftApi.addShapelessArcaneCraftingRecipe("THEJARISNOWDIAMONDS", 50,
* new ItemStack(Item.diamond,64,0), new Object[] { is });
*
* If no tag was added for "amount" then the jar would simply have had to contain any
* amount of crystal essentia.
*/
/**
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param cost the vis cost
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla recipes
*/
public static void addArcaneCraftingRecipe(String key, int cost, ItemStack par1ItemStack, Object ... par2ArrayOfObj)
{
String var3 = "";
int var4 = 0;
int var5 = 0;
int var6 = 0;
int var9;
if (par2ArrayOfObj[var4] instanceof String[])
{
String[] var7 = (String[])((String[])par2ArrayOfObj[var4++]);
String[] var8 = var7;
var9 = var7.length;
for (int var10 = 0; var10 < var9; ++var10)
{
String var11 = var8[var10];
++var6;
var5 = var11.length();
var3 = var3 + var11;
}
}
else
{
while (par2ArrayOfObj[var4] instanceof String)
{
String var13 = (String)par2ArrayOfObj[var4++];
++var6;
var5 = var13.length();
var3 = var3 + var13;
}
}
HashMap var14;
for (var14 = new HashMap(); var4 < par2ArrayOfObj.length; var4 += 2)
{
Character var16 = (Character)par2ArrayOfObj[var4];
ItemStack var17 = null;
if (par2ArrayOfObj[var4 + 1] instanceof Item)
{
var17 = new ItemStack((Item)par2ArrayOfObj[var4 + 1]);
}
else if (par2ArrayOfObj[var4 + 1] instanceof Block)
{
var17 = new ItemStack((Block)par2ArrayOfObj[var4 + 1], 1, -1);
}
else if (par2ArrayOfObj[var4 + 1] instanceof ItemStack)
{
var17 = (ItemStack)par2ArrayOfObj[var4 + 1];
}
var14.put(var16, var17);
}
ItemStack[] var15 = new ItemStack[var5 * var6];
for (var9 = 0; var9 < var5 * var6; ++var9)
{
char var18 = var3.charAt(var9);
if (var14.containsKey(Character.valueOf(var18)))
{
var15[var9] = ((ItemStack)var14.get(Character.valueOf(var18))).copy();
}
else
{
var15[var9] = null;
}
}
craftingRecipes.add(new ShapedArcaneCraftingRecipes(key, var5, var6, var15, par1ItemStack,cost));
}
/**
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param recipeKey a string value of the key used in your research.xml for this recipe to display in the thaumonomicon
* @param cost the vis cost
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla recipes
*/
public static void addArcaneCraftingRecipe(String key, String recipeKey, int cost, ItemStack par1ItemStack, Object ... par2ArrayOfObj) {
addArcaneCraftingRecipe(key,cost,par1ItemStack,par2ArrayOfObj);
ResearchList.craftingRecipesForResearch.put(recipeKey, Arrays.asList(getCraftingRecipes().size()-1));
}
/**
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param cost the vis cost
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla shapeless recipes
*/
public static void addShapelessArcaneCraftingRecipe(String key, int cost, ItemStack par1ItemStack, Object ... par2ArrayOfObj)
{
ArrayList var3 = new ArrayList();
Object[] var4 = par2ArrayOfObj;
int var5 = par2ArrayOfObj.length;
for (int var6 = 0; var6 < var5; ++var6)
{
Object var7 = var4[var6];
if (var7 instanceof ItemStack)
{
var3.add(((ItemStack)var7).copy());
}
else if (var7 instanceof Item)
{
var3.add(new ItemStack((Item)var7));
}
else
{
if (!(var7 instanceof Block))
{
throw new RuntimeException("Invalid shapeless recipe!");
}
var3.add(new ItemStack((Block)var7));
}
}
craftingRecipes.add(new ShapelessArcaneCraftingRecipes(key, par1ItemStack, var3, cost));
}
/**
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param recipeKey a string value of the key used in your research.xml for this recipe to display in the thaumonomicon
* @param cost the vis cost
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla shapeless recipes
*/
public static void addShapelessArcaneCraftingRecipe(String key, String recipeKey, int cost, ItemStack par1ItemStack, Object ... par2ArrayOfObj) {
addShapelessArcaneCraftingRecipe(key,cost,par1ItemStack,par2ArrayOfObj);
ResearchList.craftingRecipesForResearch.put(recipeKey, Arrays.asList(getCraftingRecipes().size()-1));
}
/**
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param cost the vis cost
* @param tags ObjectTags list of required aspects and their amounts. No more than 5 aspects should be used in a recipe.
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla recipes
*/
public static void addInfusionCraftingRecipe(String key, int cost, ObjectTags tags, ItemStack par1ItemStack, Object ... par2ArrayOfObj)
{
String var3 = "";
int var4 = 0;
int var5 = 0;
int var6 = 0;
int var9;
if (par2ArrayOfObj[var4] instanceof String[])
{
String[] var7 = (String[])((String[])par2ArrayOfObj[var4++]);
String[] var8 = var7;
var9 = var7.length;
for (int var10 = 0; var10 < var9; ++var10)
{
String var11 = var8[var10];
++var6;
var5 = var11.length();
var3 = var3 + var11;
}
}
else
{
while (par2ArrayOfObj[var4] instanceof String)
{
String var13 = (String)par2ArrayOfObj[var4++];
++var6;
var5 = var13.length();
var3 = var3 + var13;
}
}
HashMap var14;
for (var14 = new HashMap(); var4 < par2ArrayOfObj.length; var4 += 2)
{
Character var16 = (Character)par2ArrayOfObj[var4];
ItemStack var17 = null;
if (par2ArrayOfObj[var4 + 1] instanceof Item)
{
var17 = new ItemStack((Item)par2ArrayOfObj[var4 + 1]);
}
else if (par2ArrayOfObj[var4 + 1] instanceof Block)
{
var17 = new ItemStack((Block)par2ArrayOfObj[var4 + 1], 1, -1);
}
else if (par2ArrayOfObj[var4 + 1] instanceof ItemStack)
{
var17 = (ItemStack)par2ArrayOfObj[var4 + 1];
}
var14.put(var16, var17);
}
ItemStack[] var15 = new ItemStack[var5 * var6];
for (var9 = 0; var9 < var5 * var6; ++var9)
{
char var18 = var3.charAt(var9);
if (var14.containsKey(Character.valueOf(var18)))
{
var15[var9] = ((ItemStack)var14.get(Character.valueOf(var18))).copy();
}
else
{
var15[var9] = null;
}
}
craftingRecipes.add(new ShapedInfusionCraftingRecipes(key, var5, var6, var15, par1ItemStack,cost,tags));
}
/**
* Recipe is NBT sensitive
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param recipeKey a string value of the key used in your research.xml for this recipe to display in the thaumonomicon
* @param cost the vis cost
* @param tags ObjectTags list of required aspects and their amounts. No more than 5 aspects should be used in a recipe.
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla recipes
*/
public static void addInfusionCraftingRecipe(String key, String recipeKey, int cost, ObjectTags tags, ItemStack par1ItemStack, Object ... par2ArrayOfObj) {
addInfusionCraftingRecipe(key, cost, tags, par1ItemStack, par2ArrayOfObj);
ResearchList.craftingRecipesForResearch.put(recipeKey, Arrays.asList(getCraftingRecipes().size()-1));
}
/**
* Recipe is NBT sensitive
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param cost the vis cost
* @param tags ObjectTags list of required aspects and their amounts. No more than 5 aspects should be used in a recipe.
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla shapeless recipes
*/
public static void addShapelessInfusionCraftingRecipe(String key, int cost, ObjectTags tags, ItemStack par1ItemStack, Object ... par2ArrayOfObj)
{
ArrayList var3 = new ArrayList();
Object[] var4 = par2ArrayOfObj;
int var5 = par2ArrayOfObj.length;
for (int var6 = 0; var6 < var5; ++var6)
{
Object var7 = var4[var6];
if (var7 instanceof ItemStack)
{
var3.add(((ItemStack)var7).copy());
}
else if (var7 instanceof Item)
{
var3.add(new ItemStack((Item)var7));
}
else
{
if (!(var7 instanceof Block))
{
throw new RuntimeException("Invalid shapeless recipe!");
}
var3.add(new ItemStack((Block)var7));
}
}
craftingRecipes.add(new ShapelessInfusionCraftingRecipes(key, par1ItemStack, var3, cost,tags));
}
/**
* Recipe is NBT sensitive
* @param key the research key required for this recipe to work. Leave blank if it will work without research
* @param recipeKey a string value of the key used in your research.xml for this recipe to display in the thaumonomicon
* @param cost the vis cost
* @param tags ObjectTags list of required aspects and their amounts. No more than 5 aspects should be used in a recipe.
* @param par1ItemStack the recipe output
* @param par2ArrayOfObj the recipe. Format is exactly the same as vanilla shapeless recipes
*/
public static void addShapelessInfusionCraftingRecipe(String key, String recipeKey, int cost, ObjectTags tags, ItemStack par1ItemStack, Object ... par2ArrayOfObj) {
addShapelessInfusionCraftingRecipe(key, cost, tags, par1ItemStack, par2ArrayOfObj);
ResearchList.craftingRecipesForResearch.put(recipeKey, Arrays.asList(getCraftingRecipes().size()-1));
}
/**
* @param key the research key required for this recipe to work. Unlike the arcane crafting and infusion crafting
* recipes a recipe key is automatically created using the same key.
* See method below if the research and recipes keys do not match
* @param result the output result
* @param cost the vis cost
* @param tags the aspects required to craft this
*/
public static void addCrucibleRecipe(String key, ItemStack result, int cost, ObjectTags tags) {
getCrucibleRecipes().add(new RecipeCrucible(key, result, tags, cost));
}
/**
* @param key the research key required for this recipe to work.
* @param recipeKey a string value of the key used in your research.xml for this recipe to display in the thaumonomicon
* @param result the output result
* @param cost the vis cost
* @param tags the aspects required to craft this
*/
public static void addCrucibleRecipe(String key, String recipeKey, ItemStack result, int cost, ObjectTags tags) {
getCrucibleRecipes().add(new RecipeCrucible(key, recipeKey, result, tags, cost));
}
/**
* @param key the recipe key (NOT research key)
* @return the recipe
*/
public static RecipeCrucible getCrucibleRecipe(String key) {
for (Object r:getCrucibleRecipes()) {
if (r instanceof RecipeCrucible) {
if (((RecipeCrucible)r).key.equals(key))
return (RecipeCrucible)r;
}
}
return null;
}
/**
* @param stack the recipe result
* @return the recipe
*/
public static RecipeCrucible getCrucibleRecipe(ItemStack stack) {
for (Object r:getCrucibleRecipes()) {
if (r instanceof RecipeCrucible) {
if (((RecipeCrucible)r).recipeOutput.isItemEqual(stack))
return (RecipeCrucible)r;
}
}
return null;
}
/**
* @param stack the item
* @return the thaumcraft recipe key that produces that item. Used by the thaumonomicon drilldown feature.
*/
public static String getCraftingRecipeKey(ItemStack stack) {
for (Object r:getCraftingRecipes()) {
if (r instanceof IArcaneRecipe) {
if (ThaumcraftApiHelper.areItemsEqual(stack,((IArcaneRecipe)r).getRecipeOutput()))
return ((IArcaneRecipe)r).getKey();
}
if (r instanceof IInfusionRecipe) {
if (ThaumcraftApiHelper.areItemsEqual(stack,((IInfusionRecipe)r).getRecipeOutput()))
return ((IInfusionRecipe)r).getKey();
}
}
return "";
}
//TAGS////////////////////////////////////////
public static Map<List,ObjectTags> objectTags = new HashMap<List,ObjectTags>();
/**
* Checks to see if the passed item/block already has aspects associated with it.
* @param id
* @param meta
* @return
*/
public static boolean exists(int id, int meta) {
ObjectTags tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,meta));
if (tmp==null) {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,-1));
if (meta==-1 && tmp==null) {
int index=0;
do {
tmp = ThaumcraftApi.objectTags.get(Arrays.asList(id,index));
index++;
} while (index<16 && tmp==null);
}
if (tmp==null) return false;
}
return true;
}
/**
* Used to assign apsects to the given item/block. Here is an example of the declaration for cobblestone:<p>
* <i>ThaumcraftApi.registerObjectTag(Block.cobblestone.blockID, -1, (new ObjectTags()).add(EnumTag.ROCK, 1).add(EnumTag.DESTRUCTION, 1));</i>
* @param id
* @param meta pass -1 if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerObjectTag(int id, int meta, ObjectTags aspects) {
aspects = ThaumcraftApiHelper.cullTags(aspects);
objectTags.put(Arrays.asList(id,meta), aspects);
}
/**
* Used to assign aspects to the given item/block.
* Attempts to automatically generate aspect tags by checking registered recipes.
* Here is an example of the declaration for pistons:<p>
* <i>ThaumcraftApi.registerComplexObjectTag(Block.pistonBase.blockID, 0, (new ObjectTags()).add(EnumTag.MECHANISM, 2).add(EnumTag.MOTION, 4));</i>
* @param id
* @param meta pass -1 if all damage values of this item/block should have the same aspects
* @param aspects A ObjectTags object of the associated aspects
*/
public static void registerComplexObjectTag(int id, int meta, ObjectTags aspects ) {
if (!exists(id,meta)) {
ObjectTags tmp = ThaumcraftApiHelper.generateTags(id, meta);
if (tmp != null && tmp.size()>0) {
for(EnumTag tag:tmp.getAspects()) {
aspects.add(tag, tmp.getAmount(tag));
}
}
registerObjectTag(id,meta,aspects);
} else {
ObjectTags tmp = ThaumcraftApiHelper.getObjectTags(new ItemStack(id,1,meta));
for(EnumTag tag:aspects.getAspects()) {
tmp.merge(tag, tmp.getAmount(tag));
}
registerObjectTag(id,meta,tmp);
}
}
public static ArrayList getCrucibleRecipes() {
return crucibleRecipes;
}
//AURAS//////////////////////////////////////////////////
private static Method addFluxToClosest;
/**
* Adds flux to the node closest to the given location
* @param world
* @param x
* @param y
* @param z
* @param tags ObjectTags list of all the EnumTags and amounts of flux to add.
*/
public static void addFluxToClosest(World world, float x, float y, float z, ObjectTags tags) {
try {
if(addFluxToClosest == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
addFluxToClosest = fake.getMethod("addFluxToClosest", World.class, float.class, float.class, float.class, ObjectTags.class);
}
addFluxToClosest.invoke(null, world,x,y,z,tags);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method addFluxToClosest");
}
}
private static Method decreaseClosestAura;
/**
* Removes an amount of vis from the aura node closest to the given location
* @param world
* @param x
* @param y
* @param z
* @param amount The amount of vis to remove
* @param doit If set to false it will merely perform a check to see if there is enough vis to perform the operation.
* If set to true it will actually decrease the vis as well.
* @return It will return true if there was enough vis to perform this operation
*/
public static boolean decreaseClosestAura(World world, double x, double y, double z, int amount, boolean doit) {
boolean ret=false;
try {
if(decreaseClosestAura == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
decreaseClosestAura = fake.getMethod("decreaseClosestAura", World.class, double.class, double.class, double.class, int.class, boolean.class);
}
ret = (Boolean) decreaseClosestAura.invoke(null, world,x,y,z,amount,doit);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method decreaseClosestAura");
}
return ret;
}
private static Method increaseLowestAura;
/**
* Increases the lowest aura near the given location.
* @param world
* @param x
* @param y
* @param z
* @param amount
* @return it will return true if the operation was a success
*/
public static boolean increaseLowestAura(World world, double x, double y, double z, int amount) {
boolean ret=false;
try {
if(increaseLowestAura == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
increaseLowestAura = fake.getMethod("increaseLowestAura", World.class, double.class, double.class, double.class, int.class);
}
ret = (Boolean) increaseLowestAura.invoke(null, world,x,y,z,amount);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method increaseLowestAura");
}
return ret;
}
private static Method getClosestAuraWithinRange;
/**
* Gets the id of the closest aura node within range of the given coordinates. Only checks loaded chunks
* @param world
* @param x
* @param y
* @param z
* @param range distance (in blocks) to check
* @return returns -1 if no aura is found, otherwise returns the aura node id.
*/
public static int getClosestAuraWithinRange(World world, double x, double y, double z, double range) {
int ret=-1;
try {
if(getClosestAuraWithinRange == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
getClosestAuraWithinRange = fake.getMethod("getClosestAuraWithinRange", World.class, double.class, double.class, double.class, double.class);
}
ret = (Integer) getClosestAuraWithinRange.invoke(null, world,x,y,z,range);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method getClosestAuraWithinRange");
}
return ret;
}
private static Method getNodeCopy;
/**
* Gets an copy of the AuraNode object for the given node
* @param nodeId the int key of the aura node
* @return returns a COPY of the auranode object, not the object itself.
* Auranode values should only be altered via queNodeChanges - NEVER directly
*/
public static AuraNode getNodeCopy(int nodeId) {
AuraNode node = null;
try {
if(getNodeCopy == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
getNodeCopy = fake.getMethod("getNodeCopy", int.class);
}
node = (AuraNode) getNodeCopy.invoke(null, nodeId);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method getNodeCopy");
}
return node;
}
private static Method queueNodeChanges;
/**
* This method is used to alter the values of aura nodes. The changes specified are placed in a queue for processing by
* the aura thread.<br>
*
* For example:<br>
* queNodeChanges(55,8,0,false,null,0,0,0); //will increase node 55's current vis by 8<br>
* queNodeChanges(55,0,0,false,new ObjectTags().remove(EnumTag.FIRE,3),0,0,0); //will reduce node 55's FIRE flux levels by 3<br>
* queNodeChanges(55,11,11,false,null,0,.5f,0); //will increase node 55's current and base level by 11 and increase its y pos by .5f<br>
*
* @param nodeId
* @param levelMod the amount by which the auras vis level should be changed (positive or negative)
* @param baseMod the amount by which the auras max vis level should be changed (positive or negative)
* @param toggleLock if set to true the nodes lock state will toggle to its opposite value. Currently doesn't do much
* @param flx a ObjectTags collection of the all the flux to add (if positive) or remove (if negative) to the node
* @param x by how much the nodes x position should be altered. Should usually be less than 1
* @param y by how much the nodes y position should be altered. Should usually be less than 1
* @param z by how much the nodes z position should be altered. Should usually be less than 1
*/
public static void queueNodeChanges(int nodeId, int levelMod, int baseMod, boolean toggleLock, ObjectTags flux,
float x,float y,float z) {
try {
if(queueNodeChanges == null) {
Class fake = Class.forName("thaumcraft.common.aura.AuraManager");
queueNodeChanges = fake.getMethod("queueNodeChanges",
int.class, int.class, int.class, boolean.class, ObjectTags.class, float.class, float.class, float.class);
}
queueNodeChanges.invoke(null, nodeId, levelMod, baseMod, toggleLock, flux, x, y, z);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.aura.AuraManager method queueNodeChanges");
}
}
//BIOMES//////////////////////////////////////////////////
@Deprecated
public static HashMap<Integer,List> biomeInfo = new HashMap<Integer,List>();
/**
* Registers custom biomes with thaumcraft
* @Deprecated I will be switching over the the forge BiomeDictionary system in the future so any mods that add biomes should just make sure they are tagged correctly
* @param biomeID The id of the biome
* @param visLevel The average vis level of nodes generated in this biome
* @param tag The EnumTag associated with this biome (used to determine infused ore spawns among other things)
* @param greatwood Does this biome support greatwood trees
* @param silverwood Does this biome support silverwood trees
*/
@Deprecated
public static void registerBiomeInfo(int biomeID, int visLevel, EnumTag tag, boolean greatwood, boolean silverwood) {
biomeInfo.put(biomeID, Arrays.asList(visLevel, tag, greatwood, silverwood));
}
@Deprecated
public static int getBiomeAura(int biomeId) {
try {
return (Integer) biomeInfo.get(biomeId).get(0);
} catch (Exception e) {}
return 200;
}
@Deprecated
public static EnumTag getBiomeTag(int biomeId) {
try {
return (EnumTag) biomeInfo.get(biomeId).get(1);
} catch (Exception e) {}
return EnumTag.UNKNOWN;
}
@Deprecated
public static boolean getBiomeSupportsGreatwood(int biomeId) {
try {
return (Boolean) biomeInfo.get(biomeId).get(2);
} catch (Exception e) {}
return false;
}
@Deprecated
public static boolean getBiomeSupportsSilverwood(int biomeId) {
try {
return (Boolean) biomeInfo.get(biomeId).get(3);
} catch (Exception e) {}
return false;
}
//CROPS //////////////////////////////////////////////////////////////////////////////////////////
/**
* To define mod crops you need to use FMLInterModComms in your @Mod.Init method.
* There are two 'types' of crops you can add. Standard crops and clickable crops.
*
* Standard crops work like normal vanilla crops - they grow until a certain metadata
* value is reached and you harvest them by destroying the block and collecting the blocks.
* You need to create and ItemStack that tells the golem what block id and metadata represents
* the crop when fully grown.
* Example for vanilla wheat:
* FMLInterModComms.sendMessage("Thaumcraft", "harvestStandardCrop", new ItemStack(Block.crops,1,7));
*
* Clickable crops are crops that you right click to gather their bounty instead of destroying them.
* As for standard crops, you need to create and ItemStack that tells the golem what block id
* and metadata represents the crop when fully grown. The golem will trigger the blocks onBlockActivated method.
* Example (this will technically do nothing since clicking wheat does nothing, but you get the idea):
* FMLInterModComms.sendMessage("Thaumcraft", "harvestClickableCrop", new ItemStack(Block.crops,1,7));
*/
@Deprecated
public static HashMap<Integer,Integer> crops = new HashMap<Integer,Integer>();
/**
* This is used to add mod crops to the list of crops harvested by golems
* that do not use the standard crop growth pattern<br>
* (i.e. being an instance of BlockCrops and being fully grown at meta 7).<br>
* Only seeds implementing IPlantable will be replanted.
* @param blockID the block id of the crop
* @param grownMeta the metadata value when the crop is considered fully grown.
* The block with this id and meta will be the one the golem breaks.
*/
@Deprecated
public static void addHarvestableCrop(int blockID, int grownMeta) {
crops.put(blockID, grownMeta);
}
}

View File

@ -0,0 +1,103 @@
package thaumcraft.api;
import java.lang.reflect.Method;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.FMLLog;
public class ThaumcraftApiHelper {
public static ObjectTags cullTags(ObjectTags temp) {
while (temp!=null && temp.size()>5) {
EnumTag lowest = null;
int low = Integer.MAX_VALUE;
for (EnumTag tag:temp.getAspects()) {
if (temp.getAmount(tag)<low) {
low = temp.getAmount(tag);
lowest = tag;
}
}
temp.tags.remove(lowest);
}
return temp;
}
public static boolean areItemsEqual(ItemStack s1,ItemStack s2)
{
if (s1.isItemStackDamageable() && s2.isItemStackDamageable())
{
return s1.itemID == s2.itemID;
} else
return s1.itemID == s2.itemID && s1.getItemDamage() == s2.getItemDamage();
}
static Method isResearchComplete;
static Method getObjectTags;
static Method getBonusTags;
static Method generateTags;
public static boolean isResearchComplete(String username, String researchkey) {
boolean ot = false;
try {
if(isResearchComplete == null) {
Class fake = Class.forName("thaumcraft.common.research.ResearchManager");
isResearchComplete = fake.getMethod("isResearchComplete", String.class, String.class);
}
ot = (Boolean) isResearchComplete.invoke(null, username, researchkey);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.research.ResearchManager method isResearchComplete");
}
return ot;
}
public static ItemStack getStackInRowAndColumn(Object instance, int row, int column) {
ItemStack ot = null;
try {
Class fake = Class.forName("thaumcraft.common.tiles.TileMagicWorkbench");
Method getStackInRowAndColumn = fake.getMethod("getStackInRowAndColumn", int.class, int.class);
ot = (ItemStack) getStackInRowAndColumn.invoke(instance, row, column);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.tiles.TileMagicWorkbench method getStackInRowAndColumn");
}
return ot;
}
public static ObjectTags getObjectTags(ItemStack is) {
ObjectTags ot = null;
try {
if(getObjectTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
getObjectTags = fake.getMethod("getObjectTags", ItemStack.class);
}
ot = (ObjectTags) getObjectTags.invoke(null, is);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method getObjectTags");
}
return ot;
}
public static ObjectTags getBonusObjectTags(ItemStack is,ObjectTags ot) {
try {
if(getBonusTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
getBonusTags = fake.getMethod("getBonusTags", ItemStack.class, ObjectTags.class);
}
ot = (ObjectTags) getBonusTags.invoke(null, is, ot);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method getBonusTags");
}
return ot;
}
public static ObjectTags generateTags(int id, int meta) {
try {
if(generateTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.ThaumcraftCraftingManager");
generateTags = fake.getMethod("generateTags", int.class, int.class);
}
return (ObjectTags) generateTags.invoke(null, id, meta);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.ThaumcraftCraftingManager method generateTags");
}
return null;
}
}

View File

@ -0,0 +1,85 @@
package thaumcraft.api.aspects;
import java.util.HashMap;
public class Aspect {
String tag;
Aspect[] components;
public Aspect(String tag, Aspect[] components) {
this.tag = tag;
this.components = components;
aspects.put(tag, this);
}
public Aspect(String tag) {
this.tag = tag;
aspects.put(tag, this);
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Aspect[] getComponents() {
return components;
}
public void setComponents(Aspect[] components) {
this.components = components;
}
///////////////////////////////
public static HashMap<String,Aspect> aspects = new HashMap<String,Aspect>();
//PRIMAL
public static final Aspect AIR = new Aspect("Air");
public static final Aspect EARTH = new Aspect("Earth");
public static final Aspect FIRE = new Aspect("Fire");
public static final Aspect WATER = new Aspect("Water");
public static final Aspect POSITIVE = new Aspect("Positive");
public static final Aspect NEGATIVE = new Aspect("Negative");
public static final Aspect ORDER = new Aspect("Order");
public static final Aspect CHAOS = new Aspect("Chaos");
//SECONDARY TODO
public static final Aspect VOID = new Aspect("Void", new Aspect[] {NEGATIVE, POSITIVE});
public static final Aspect LIGHT = new Aspect("Light", new Aspect[] {AIR, FIRE});
public static final Aspect DARKNESS = new Aspect("Darkness", new Aspect[] {VOID, LIGHT});
public static final Aspect ASTRAL = new Aspect("Astral", new Aspect[] {VOID, DARKNESS});
public static final Aspect ENERGY = new Aspect("Energy", new Aspect[] {POSITIVE, FIRE});
public static final Aspect LIFE = new Aspect("Life", new Aspect[] {POSITIVE, ENERGY});
public static final Aspect DEATH = new Aspect("Death", new Aspect[] {NEGATIVE, ENERGY});
public static final Aspect MOTION = new Aspect("Motion", new Aspect[] {AIR, ORDER});
public static final Aspect WEATHER = new Aspect("Weather", new Aspect[] {AIR, CHAOS});
public static final Aspect STONE = new Aspect("Stone", new Aspect[] {EARTH, ORDER});
public static final Aspect METAL = new Aspect("Metal", new Aspect[] {STONE, FIRE});
public static final Aspect SAND = new Aspect("Sand", new Aspect[] {AIR, STONE});
public static final Aspect SOUL = new Aspect("Soul", new Aspect[] {DEATH, LIFE});
public static final Aspect HEAL = new Aspect("Heal", new Aspect[] {POSITIVE, LIFE});
public static final Aspect HARM = new Aspect("Harm", new Aspect[] {NEGATIVE, LIFE});
public static final Aspect ANIMATE = new Aspect("Animate",new Aspect[] {MOTION, LIFE});
public static final Aspect MAN = new Aspect("Man", new Aspect[] {LIFE, SOUL});
public static final Aspect BEAST = new Aspect("Beast", new Aspect[] {LIFE, CHAOS});
public static final Aspect BIRD = new Aspect("Bird", new Aspect[] {BEAST, AIR});
public static final Aspect FISH = new Aspect("Fish", new Aspect[] {BEAST, WATER});
public static final Aspect SEED = new Aspect("Seed", new Aspect[] {LIFE, EARTH});
public static final Aspect TREE = new Aspect("Tree", new Aspect[] {SEED, EARTH});
public static final Aspect TOOL = new Aspect("Tool", new Aspect[] {MAN, METAL});
public static final Aspect MINE = new Aspect("Mine", new Aspect[] {MAN, STONE});
public static final Aspect WOOD = new Aspect("Wood", new Aspect[] {TREE, TOOL});
public static final Aspect MACHINE = new Aspect("Machine", new Aspect[] {TOOL, ORDER});
// public static final Aspect TRAVEL = new Aspect("Travel", new Aspect[] {MOTION, EARTH});
// public static final Aspect TELEPORT = new Aspect("Teleport", new Aspect[] {TRAVEL, VOID});
// public static final Aspect GLASS = new Aspect("Glass", new Aspect[] {SAND, FIRE});
// public static final Aspect CLAY = new Aspect("Clay", new Aspect[] {SAND, LIFE});
}

View File

@ -0,0 +1,38 @@
package thaumcraft.api.aura;
import java.io.Serializable;
import thaumcraft.api.ObjectTags;
public class AuraNode implements Serializable {
//key
public int key;
//aura
public short level;
public short baseLevel;
public ObjectTags flux = new ObjectTags();
public EnumNodeType type;
//location
public int dimension;
public double xPos;
public double yPos;
public double zPos;
public boolean locked;
public AuraNode(int key, short lvl, EnumNodeType type, int dim, int x, int y, int z) {
this.key = key;
this.level = lvl;
this.baseLevel = lvl;
this.type = type;
this.dimension = dim;
this.xPos = x+.5d;
this.yPos = y+.5d;
this.zPos = z+.5d;
}
public AuraNode() {
}
}

View File

@ -0,0 +1,21 @@
package thaumcraft.api.aura;
public enum EnumNodeType {
NORMAL,
PURE,
DARK,
UNSTABLE;
public static final EnumNodeType[] VALID_TYPES = {NORMAL,PURE,DARK,UNSTABLE};
public static EnumNodeType getType(int id)
{
if (id >= 0 && id < VALID_TYPES.length)
{
return VALID_TYPES[id];
}
return NORMAL;
}
}

View File

@ -0,0 +1,30 @@
package thaumcraft.api.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public interface IArcaneRecipe
{
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
boolean matches(IInventory var1, EntityPlayer player);
/**
* Returns an Item that is the result of this recipe
*/
ItemStack getCraftingResult(IInventory var1);
/**
* Returns the size of the recipe area
*/
int getRecipeSize();
ItemStack getRecipeOutput();
int getCost();
String getKey();
}

View File

@ -0,0 +1,30 @@
package thaumcraft.api.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import thaumcraft.api.ObjectTags;
public interface IInfusionRecipe
{
/**
* Used to check if a recipe matches current crafting inventory
* @param player
*/
boolean matches(IInventory var1, EntityPlayer player);
/**
* Returns an Item that is the result of this recipe
*/
ItemStack getCraftingResult(IInventory var1);
/**
* Returns the size of the recipe area
*/
int getRecipeSize();
ItemStack getRecipeOutput();
int getCost();
ObjectTags getTags();
String getKey();
}

View File

@ -0,0 +1,51 @@
package thaumcraft.api.crafting;
import net.minecraft.item.ItemStack;
import thaumcraft.api.EnumTag;
import thaumcraft.api.ObjectTags;
public class RecipeCrucible {
public ItemStack recipeOutput;
public ObjectTags tags;
public String key;
public String researchKey;
public int cost;
public RecipeCrucible(String researchKey, String key, ItemStack result, ObjectTags tags, int cost) {
recipeOutput = result;
this.tags = tags;
this.key = key;
this.researchKey = researchKey;
this.cost = cost;
}
public RecipeCrucible(String key, ItemStack result, ObjectTags tags, int cost) {
recipeOutput = result;
this.tags = tags;
this.key = key;
this.researchKey = key;
this.cost = cost;
}
public boolean matches(ObjectTags itags) {
if (itags==null) return false;
for (EnumTag tag:tags.getAspects()) {
if (itags.getAmount(tag)<tags.getAmount(tag)) return false;
}
return true;
}
public ObjectTags removeMatching(ObjectTags itags) {
ObjectTags temptags = new ObjectTags();
temptags.tags.putAll(itags.tags);
for (EnumTag tag:tags.getAspects()) {
if (!temptags.reduceAmount(tag, tags.getAmount(tag))) return null;
}
itags = temptags;
return itags;
}
}

View File

@ -0,0 +1,167 @@
package thaumcraft.api.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
public class ShapedArcaneCraftingRecipes implements IArcaneRecipe
{
/** How many horizontal slots this recipe is wide. */
public int recipeWidth;
/** How many vertical slots this recipe uses. */
public int recipeHeight;
public String key;
public int cost;
/** Is a array of ItemStack that composes the recipe. */
public ItemStack[] recipeItems;
/** Is the ItemStack that you get when craft the recipe. */
private ItemStack recipeOutput;
/** Is the itemID of the output item that you get when craft the recipe. */
public final int recipeOutputItemID;
public ShapedArcaneCraftingRecipes(String key, int par1, int par2, ItemStack[] par3ArrayOfItemStack, ItemStack par4ItemStack, int cost)
{
this.recipeOutputItemID = par4ItemStack.itemID;
this.recipeWidth = par1;
this.recipeHeight = par2;
this.recipeItems = par3ArrayOfItemStack;
this.recipeOutput = par4ItemStack;
this.key = key;
this.cost = cost;
}
public ItemStack getRecipeOutput()
{
return this.recipeOutput;
}
/**
* Used to check if a recipe matches current crafting inventory
*/
public boolean matches(IInventory par1InventoryCrafting, EntityPlayer player)
{
if (key.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, key)) {
return false;
}
for (int var2 = 0; var2 <= 3 - this.recipeWidth; ++var2)
{
for (int var3 = 0; var3 <= 3 - this.recipeHeight; ++var3)
{
if (this.checkMatch(par1InventoryCrafting, var2, var3, true))
{
return true;
}
if (this.checkMatch(par1InventoryCrafting, var2, var3, false))
{
return true;
}
}
}
return false;
}
/**
* Checks if the region of a crafting inventory is match for the recipe.
*/
private boolean checkMatch(IInventory par1InventoryCrafting, int par2, int par3, boolean par4)
{
for (int var5 = 0; var5 < 3; ++var5)
{
for (int var6 = 0; var6 < 3; ++var6)
{
int var7 = var5 - par2;
int var8 = var6 - par3;
ItemStack var9 = null;
if (var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight)
{
if (par4)
{
var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth];
}
else
{
var9 = this.recipeItems[var7 + var8 * this.recipeWidth];
}
}
ItemStack var10 = ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var5, var6);
if (var10 != null || var9 != null)
{
if (var10 == null && var9 != null || var10 != null && var9 == null)
{
return false;
}
if (var9.itemID != var10.itemID)
{
return false;
}
if (var9.getItemDamage() != OreDictionary.WILDCARD_VALUE && var9.getItemDamage() != var10.getItemDamage())
{
return false;
}
if (var9.hasTagCompound()) {
NBTTagCompound tc = var9.getTagCompound();
for (Object tag:tc.getTags().toArray()) {
NBTBase base = (NBTBase)tag;
Class nc = NBTBase.newTag(base.getId(), base.getName()).getClass();
if (!(var10.hasTagCompound() &&
nc.cast(var10.getTagCompound().getTag(base.getName())).equals(nc.cast(base)))) {
return false;
}
}
}
}
}
}
return true;
}
/**
* Returns an Item that is the result of this recipe
*/
public ItemStack getCraftingResult(IInventory par1InventoryCrafting)
{
return new ItemStack(this.recipeOutput.itemID, this.recipeOutput.stackSize, this.recipeOutput.getItemDamage());
}
/**
* Returns the size of the recipe area
*/
public int getRecipeSize()
{
return this.recipeWidth * this.recipeHeight;
}
@Override
public int getCost() {
return cost;
}
@Override
public String getKey() {
return key;
}
}

View File

@ -0,0 +1,171 @@
package thaumcraft.api.crafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ObjectTags;
import thaumcraft.api.ThaumcraftApiHelper;
public class ShapedInfusionCraftingRecipes implements IInfusionRecipe
{
/** How many horizontal slots this recipe is wide. */
public int recipeWidth;
/** How many vertical slots this recipe uses. */
public int recipeHeight;
public String key;
@Override
public String getKey() {
return key;
}
public int cost;
public ObjectTags tags;
/** Is a array of ItemStack that composes the recipe. */
public ItemStack[] recipeItems;
/** Is the ItemStack that you get when craft the recipe. */
private ItemStack recipeOutput;
/** Is the itemID of the output item that you get when craft the recipe. */
public final int recipeOutputItemID;
public ShapedInfusionCraftingRecipes(String key, int par1, int par2, ItemStack[] par3ArrayOfItemStack, ItemStack par4ItemStack, int cost, ObjectTags tags)
{
this.recipeOutputItemID = par4ItemStack.itemID;
this.recipeWidth = par1;
this.recipeHeight = par2;
this.recipeItems = par3ArrayOfItemStack;
this.recipeOutput = par4ItemStack;
this.key = key;
this.cost = cost;
this.tags = tags;
}
public ItemStack getRecipeOutput()
{
return this.recipeOutput;
}
/**
* Used to check if a recipe matches current crafting inventory
*/
public boolean matches(IInventory par1InventoryCrafting, EntityPlayer player)
{
if (key.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, key)) {
return false;
}
for (int var2 = 0; var2 <= 3 - this.recipeWidth; ++var2)
{
for (int var3 = 0; var3 <= 3 - this.recipeHeight; ++var3)
{
if (this.checkMatch(par1InventoryCrafting, var2, var3, true))
{
return true;
}
if (this.checkMatch(par1InventoryCrafting, var2, var3, false))
{
return true;
}
}
}
return false;
}
/**
* Checks if the region of a crafting inventory is match for the recipe.
*/
private boolean checkMatch(IInventory par1InventoryCrafting, int par2, int par3, boolean par4)
{
for (int var5 = 0; var5 < 3; ++var5)
{
for (int var6 = 0; var6 < 3; ++var6)
{
int var7 = var5 - par2;
int var8 = var6 - par3;
ItemStack var9 = null;
if (var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight)
{
if (par4)
{
var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth];
}
else
{
var9 = this.recipeItems[var7 + var8 * this.recipeWidth];
}
}
ItemStack var10 = ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var5, var6);
if (var10 != null || var9 != null)
{
if (var10 == null && var9 != null || var10 != null && var9 == null)
{
return false;
}
if (var9.itemID != var10.itemID)
{
return false;
}
if (var9.getItemDamage() != OreDictionary.WILDCARD_VALUE && var9.getItemDamage() != var10.getItemDamage())
{
return false;
}
if (var9.hasTagCompound()) {
NBTTagCompound tc = var9.getTagCompound();
for (Object tag:tc.getTags().toArray()) {
NBTBase base = (NBTBase)tag;
Class nc = NBTBase.newTag(base.getId(), base.getName()).getClass();
if (!(var10.hasTagCompound() &&
nc.cast(var10.getTagCompound().getTag(base.getName())).equals(nc.cast(base)))) {
return false;
}
}
}
}
}
}
return true;
}
/**
* Returns an Item that is the result of this recipe
*/
public ItemStack getCraftingResult(IInventory par1InventoryCrafting)
{
return new ItemStack(this.recipeOutput.itemID, this.recipeOutput.stackSize, this.recipeOutput.getItemDamage());
}
/**
* Returns the size of the recipe area
*/
public int getRecipeSize()
{
return this.recipeWidth * this.recipeHeight;
}
@Override
public int getCost() {
return cost;
}
@Override
public ObjectTags getTags() {
return tags;
}
}

View File

@ -0,0 +1,127 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ThaumcraftApiHelper;
public class ShapelessArcaneCraftingRecipes implements IArcaneRecipe
{
/** Is the ItemStack that you get when craft the recipe. */
private final ItemStack recipeOutput;
/** Is a List of ItemStack that composes the recipe. */
public final List recipeItems;
public String key;
@Override
public String getKey() {
return key;
}
public int cost;
public ShapelessArcaneCraftingRecipes(String key, ItemStack par1ItemStack, List par2List, int cost)
{
this.recipeOutput = par1ItemStack;
this.recipeItems = par2List;
this.key = key;
this.cost = cost;
}
public ItemStack getRecipeOutput()
{
return this.recipeOutput;
}
/**
* Used to check if a recipe matches current crafting inventory
*/
public boolean matches(IInventory par1InventoryCrafting, EntityPlayer player)
{
if (key.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, key)) {
return false;
}
ArrayList var2 = new ArrayList(this.recipeItems);
for (int var3 = 0; var3 < 3; ++var3)
{
for (int var4 = 0; var4 < 3; ++var4)
{
ItemStack var5 = ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var4, var3);
if (var5 != null)
{
boolean var6 = false;
Iterator var7 = var2.iterator();
while (var7.hasNext())
{
ItemStack var8 = (ItemStack)var7.next();
if (var5.itemID == var8.itemID && (var8.getItemDamage() == OreDictionary.WILDCARD_VALUE || var5.getItemDamage() == var8.getItemDamage()))
{
boolean matches=true;
if (var8.hasTagCompound()) {
NBTTagCompound tc = var8.getTagCompound();
for (Object tag:tc.getTags().toArray()) {
NBTBase base = (NBTBase)tag;
Class nc = NBTBase.newTag(base.getId(), base.getName()).getClass();
if (!(var5.hasTagCompound() &&
nc.cast(var5.getTagCompound().getTag(base.getName())).equals(nc.cast(base)))) {
matches=false;
break;
}
}
}
if (matches) {
var6 = true;
var2.remove(var8);
break;
}
}
}
if (!var6)
{
return false;
}
}
}
}
return var2.isEmpty();
}
/**
* Returns an Item that is the result of this recipe
*/
public ItemStack getCraftingResult(IInventory par1InventoryCrafting)
{
return this.recipeOutput.copy();
}
/**
* Returns the size of the recipe area
*/
public int getRecipeSize()
{
return this.recipeItems.size();
}
@Override
public int getCost() {
return cost;
}
}

View File

@ -0,0 +1,136 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ObjectTags;
import thaumcraft.api.ThaumcraftApiHelper;
public class ShapelessInfusionCraftingRecipes implements IInfusionRecipe
{
/** Is the ItemStack that you get when craft the recipe. */
private final ItemStack recipeOutput;
/** Is a List of ItemStack that composes the recipe. */
public final List recipeItems;
public String key;
@Override
public String getKey() {
return key;
}
public int cost;
public ObjectTags tags;
public ShapelessInfusionCraftingRecipes(String key, ItemStack par1ItemStack, List par2List, int cost, ObjectTags tags)
{
this.recipeOutput = par1ItemStack;
this.recipeItems = par2List;
this.key = key;
this.cost = cost;
this.tags = tags;
}
public ItemStack getRecipeOutput()
{
return this.recipeOutput;
}
/**
* Used to check if a recipe matches current crafting inventory
*/
public boolean matches(IInventory par1InventoryCrafting, EntityPlayer player)
{
if (key.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, key)) {
return false;
}
ArrayList var2 = new ArrayList(this.recipeItems);
for (int var3 = 0; var3 < 3; ++var3)
{
for (int var4 = 0; var4 < 3; ++var4)
{
ItemStack var5 = ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var4, var3);
if (var5 != null)
{
boolean var6 = false;
Iterator var7 = var2.iterator();
while (var7.hasNext())
{
ItemStack var8 = (ItemStack)var7.next();
if (var5.itemID == var8.itemID && (var8.getItemDamage() == OreDictionary.WILDCARD_VALUE || var5.getItemDamage() == var8.getItemDamage()))
{
boolean matches=true;
if (var8.hasTagCompound()) {
NBTTagCompound tc = var8.getTagCompound();
for (Object tag:tc.getTags().toArray()) {
NBTBase base = (NBTBase)tag;
Class nc = NBTBase.newTag(base.getId(), base.getName()).getClass();
if (!(var5.hasTagCompound() &&
nc.cast(var5.getTagCompound().getTag(base.getName())).equals(nc.cast(base)))) {
matches=false;
break;
}
}
}
if (matches) {
var6 = true;
var2.remove(var8);
break;
}
}
}
if (!var6)
{
return false;
}
}
}
}
return var2.isEmpty();
}
/**
* Returns an Item that is the result of this recipe
*/
public ItemStack getCraftingResult(IInventory par1InventoryCrafting)
{
return this.recipeOutput.copy();
}
/**
* Returns the size of the recipe area
*/
public int getRecipeSize()
{
return this.recipeItems.size();
}
@Override
public int getCost() {
return cost;
}
@Override
public ObjectTags getTags() {
return tags;
}
}

View File

@ -0,0 +1,134 @@
package thaumcraft.api.crafting;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.ObjectTags;
import thaumcraft.api.ThaumcraftApiHelper;
public class ShapelessInfusionCraftingWithNBTRecipes implements IInfusionRecipe
{
/** Is the ItemStack that you get when craft the recipe. */
private final ItemStack recipeOutput;
/** Is a List of ItemStack that composes the recipe. */
public final List recipeItems;
/** Is a List of nbt key/value pairs. */
public final List<NBTBase> nbtList;
public String key;
@Override
public String getKey() {
return key;
}
public int cost;
public ObjectTags tags;
public ShapelessInfusionCraftingWithNBTRecipes(String key,
ItemStack par1ItemStack,
List par2List, int cost, ObjectTags tags,
List<NBTBase> nbtList)
{
this.recipeOutput = par1ItemStack;
this.recipeItems = par2List;
this.key = key;
this.cost = cost;
this.tags = tags;
this.nbtList = nbtList;
}
public ItemStack getRecipeOutput()
{
return this.recipeOutput;
}
/**
* Used to check if a recipe matches current crafting inventory
*/
public boolean matches(IInventory par1InventoryCrafting, EntityPlayer player)
{
if (key.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.username, key)) {
return false;
}
ArrayList var2 = new ArrayList(this.recipeItems);
for (int var3 = 0; var3 < 3; ++var3)
{
for (int var4 = 0; var4 < 3; ++var4)
{
ItemStack var5 = ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var4, var3);
if (var5 != null)
{
boolean var6 = false;
Iterator var7 = var2.iterator();
b1:
while (var7.hasNext())
{
ItemStack var8 = (ItemStack)var7.next();
if (var5.itemID == var8.itemID && (var8.getItemDamage() == OreDictionary.WILDCARD_VALUE || var5.getItemDamage() == var8.getItemDamage()))
{
for (NBTBase nbt:nbtList) {
try {
Class nc = NBTBase.newTag(nbt.getId(), nbt.getName()).getClass();
if (var5.hasTagCompound() &&
nc.cast(var5.getTagCompound().getTag(nbt.getName())).equals(nc.cast(nbt))) {
var6 = true;
var2.remove(var8);
break b1;
}
} catch (Exception e) {/*probably classcast*/}
}
}
}
if (!var6)
{
return false;
}
}
}
}
return var2.isEmpty();
}
/**
* Returns an Item that is the result of this recipe
*/
public ItemStack getCraftingResult(IInventory par1InventoryCrafting)
{
return this.recipeOutput.copy();
}
/**
* Returns the size of the recipe area
*/
public int getRecipeSize()
{
return this.recipeItems.size();
}
@Override
public int getCost() {
return cost;
}
@Override
public ObjectTags getTags() {
return tags;
}
}

View File

@ -0,0 +1,9 @@
package thaumcraft.api.research;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface IScanEventHandler {
ScanResult scanPhenomena(ItemStack stack, World world, EntityPlayer player);
}

View File

@ -0,0 +1,274 @@
package thaumcraft.api.research;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import thaumcraft.api.ObjectTags;
import thaumcraft.api.ThaumcraftApi;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ResearchItem
{
/**
* A short string used as a key for this research. Must be unique
*/
public final String key;
/**
* The name of the research shown in the thaumonomicon
*/
public String name;
/**
* The blurb text shown below the research name in the thaumonomicon
*/
public String popupText;
/**
* A longer description of the research. This is the text shown in the handheld research scroll and the research table.
*/
public String longText;
/**
* The aspect tags and their values required to complete this research
*/
public final ObjectTags tags;
/**
* This links to any research that needs to be completed before this research can be discovered or learnt.
*/
public ResearchItem[] parents = null;
/**
* Like parent above, but a line will not be displayed in the thaumonomicon linking them. Just used to prevent clutter.
*/
public ResearchItem[] parentsHidden = null;
/**
* any research linked to this that will be unlocked automatically when this research is complete
*/
public ResearchItem[] siblings = null;
/**
* the horizontal position of the research icon
*/
public final int displayColumn;
/**
* the vertical position of the research icon
*/
public final int displayRow;
/**
* the itemstack of an item or block that will be used as the icon for this research
*/
public final ItemStack itemStack;
/**
* the index within the research.png file used for this research if it does not use an item icon
*/
public final int iconIndex;
/**
* Special research has a spiky border. Used for important research milestones.
*/
private boolean isSpecial;
/**
* This indicates if the research should use a circular icon border. Usually used for research that doesn't
* have recipes or that unlocks automatically via the sibling system
*/
private boolean isStub;
/**
* Indicates research that cannot be gained by normal means (either via normal or lost research),
* but still uses a normal icon. Works much like isStub but is handy for mods that wish to add research
* through their own means and keep a normal icon.
*/
private boolean isAlternate;
/**
* Hidden research does not display in the thaumonomicon until discovered
*/
private boolean isHidden;
/**
* Lost research can only be discovered via knowledge fragments
*/
private boolean isLost;
/**
* These research items will automatically unlock for all players on game start
*/
private boolean isAutoUnlock;
public ResearchItem(String par1, ObjectTags tags, int par3, int par4, int icon)
{
this(par1, tags, par3, par4, (ItemStack)null, icon);
}
public ResearchItem(String par1, ObjectTags tags, int par3, int par4, ItemStack par5Item)
{
this(par1, tags, par3, par4, par5Item, -1);
}
public ResearchItem(String par1, ObjectTags tags, int par3, int par4, Item par5Item)
{
this(par1, tags, par3, par4, new ItemStack(par5Item), -1);
}
public ResearchItem(String par1, ObjectTags tags, int par3, int par4, Block par5Block)
{
this(par1, tags, par3, par4, new ItemStack(par5Block), -1);
}
public ResearchItem(String par1, ObjectTags tags, int par3, int par4, ItemStack par5ItemStack, int icon)
{
this.key = par1;
this.tags = tags;
this.name = "";
this.longText = "";
this.popupText = "";
Element el = ThaumcraftApi.researchDoc.getElementById(key);
if (el!=null) {
NodeList children = el.getChildNodes();
for (int a=0;a<children.getLength();a++) {
if (children.item(a).getNodeName().equals("name")) {
this.name = children.item(a).getTextContent();
} else
if (children.item(a).getNodeName().equals("longText")) {
this.longText = children.item(a).getTextContent();
} else
if (children.item(a).getNodeName().equals("popupText") ) {
this.popupText = children.item(a).getTextContent();
}
}
}
this.itemStack = par5ItemStack;
this.iconIndex = icon;
this.displayColumn = par3;
this.displayRow = par4;
if (par3 < ResearchList.minDisplayColumn)
{
ResearchList.minDisplayColumn = par3;
}
if (par4 < ResearchList.minDisplayRow)
{
ResearchList.minDisplayRow = par4;
}
if (par3 > ResearchList.maxDisplayColumn)
{
ResearchList.maxDisplayColumn = par3;
}
if (par4 > ResearchList.maxDisplayRow)
{
ResearchList.maxDisplayRow = par4;
}
}
public ResearchItem setSpecial()
{
this.isSpecial = true;
return this;
}
public ResearchItem setStub()
{
this.isStub = true;
return this;
}
public ResearchItem setAlternate()
{
this.isAlternate = true;
return this;
}
public ResearchItem setHidden()
{
this.isHidden = true;
return this;
}
public ResearchItem setLost()
{
this.isLost = true;
return this;
}
public ResearchItem setParents(ResearchItem... par)
{
this.parents = par;
return this;
}
public ResearchItem setParentsHidden(ResearchItem... par)
{
this.parentsHidden = par;
return this;
}
public ResearchItem setSiblings(ResearchItem... sib)
{
this.siblings = sib;
return this;
}
public ResearchItem registerResearchItem()
{
ResearchList.research.put(key, this);
return this;
}
@SideOnly(Side.CLIENT)
public String getName()
{
return this.name;
}
@SideOnly(Side.CLIENT)
public boolean getSpecial()
{
return this.isSpecial;
}
public boolean getStub()
{
return this.isStub;
}
public boolean getAlternate()
{
return this.isAlternate;
}
public boolean getHidden()
{
return this.isHidden;
}
public boolean getLost()
{
return this.isLost;
}
public boolean getAutoUnlock() {
return isAutoUnlock;
}
public ResearchItem setAutoUnlock()
{
this.isAutoUnlock = true;
return this;
}
}

View File

@ -0,0 +1,91 @@
package thaumcraft.api.research;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import thaumcraft.api.EnumTag;
public class ResearchList {
/** Is the smallest column used on the GUI. */
public static int minDisplayColumn;
/** Is the smallest row used on the GUI. */
public static int minDisplayRow;
/** Is the biggest column used on the GUI. */
public static int maxDisplayColumn;
/** Is the biggest row used on the GUI. */
public static int maxDisplayRow;
//Research
public static Map<String, ResearchItem> research = new HashMap<String,ResearchItem>();
public static Map<String, List> craftingRecipesForResearch = new HashMap<String, List>();
//
/**
* @param key
* @return the research item linked to this key
*/
public static ResearchItem getResearch(String key) {
return research.get(key);
}
/**
* @param key
* @return the name of the research linked to this key
*/
public static String getResearchName(String key) {
ResearchItem rr = research.get(key);
if (rr==null) return "";
return rr.name;
}
/**
* @param key
* @return a list of the enumtags used in this research. returns the numeric values and not the actual enum
*/
public static byte[] getResearchTags(String key) {
ResearchItem rr = research.get(key);
if (rr==null) return null;
byte[] output = new byte[rr.tags.size()];
EnumTag[] et = rr.tags.getAspects();
for (int a=0;a<rr.tags.size();a++) {
output[a] = (byte) et[a].id;
}
return output;
}
/**
* @param key
* @return the aspect enumtag ordinal with the highest value. Used to determine scroll color and similar things
*/
public static int getResearchPrimaryTag(String key) {
int t=0;
int amt=0;
ResearchItem rr = research.get(key);
if (rr==null) return 0;
for (EnumTag tag:rr.tags.getAspects()) {
if (rr.tags.getAmount(tag)>amt) {
t=tag.id;
amt=rr.tags.getAmount(tag);
};
}
return t;
}
public static int getResearchAmount(String key, EnumTag tag) {
ResearchItem rr = research.get(key);
if (rr==null) return 0;
return rr.tags.getAmount(tag);
}
}

View File

@ -0,0 +1,14 @@
package thaumcraft.api.research;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ResearchPlayer {
public Map<String,List<String>> researchCompleted = new HashMap<String,List<String>>();
public Map<String,List<Short[]>> objectsScanned = new HashMap<String,List<Short[]>>();
public Map<String,List<String>> entitiesScanned = new HashMap<String,List<String>>();
public Map<String,List<String>> phenomenaScanned = new HashMap<String,List<String>>();
}

View File

@ -0,0 +1,39 @@
package thaumcraft.api.research;
import net.minecraft.entity.Entity;
public class ScanResult {
public byte type = 0; //1=blocks,2=entities,3=phenomena
public int blockId;
public int blockMeta;
public Entity entity;
public String phenomena;
public ScanResult(byte type, int blockId, int blockMeta, Entity entity,
String phenomena) {
super();
this.type = type;
this.blockId = blockId;
this.blockMeta = blockMeta;
this.entity = entity;
this.phenomena = phenomena;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ScanResult) {
ScanResult sr = (ScanResult) obj;
if (type != sr.type)
return false;
if (type == 1
&& (blockId != sr.blockId || blockMeta != sr.blockMeta))
return false;
if (type == 2 && entity.entityId != sr.entity.entityId)
return false;
if (type == 3 && !phenomena.equals(sr.phenomena))
return false;
}
return true;
}
}