Bugfixes and stuff

This commit is contained in:
Jeremy Diamond committed 2014-12-21 09:46:45 -08:00
1 parent 0f75db6587
commit ffabe6945e
27 files changed
+1057 -349

No files matched your search

@@ -0,0 +1,108 @@
package thaumcraft.api;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
public class BlockCoordinates implements Comparable
{
public int x;
/** the y coordinate */
public int y;
/** the z coordinate */
public int z;
public BlockCoordinates() {}
public BlockCoordinates(int par1, int par2, int par3)
{
this.x = par1;
this.y = par2;
this.z = par3;
}
public BlockCoordinates(TileEntity tile)
{
this.x = tile.xCoord;
this.y = tile.yCoord;
this.z = tile.zCoord;
}
public BlockCoordinates(BlockCoordinates par1ChunkCoordinates)
{
this.x = par1ChunkCoordinates.x;
this.y = par1ChunkCoordinates.y;
this.z = par1ChunkCoordinates.z;
}
public boolean equals(Object par1Obj)
{
if (!(par1Obj instanceof BlockCoordinates))
{
return false;
}
else
{
BlockCoordinates coordinates = (BlockCoordinates)par1Obj;
return this.x == coordinates.x && this.y == coordinates.y && this.z == coordinates.z ;
}
}
public int hashCode()
{
return this.x + this.y << 8 + this.z << 16;
}
/**
* Compare the coordinate with another coordinate
*/
public int compareWorldCoordinate(BlockCoordinates par1)
{
return this.y == par1.y ? (this.z == par1.z ? this.x - par1.x : this.z - par1.z) : this.y - par1.y;
}
public void set(int par1, int par2, int par3, int d)
{
this.x = par1;
this.y = par2;
this.z = par3;
}
/**
* Returns the squared distance between this coordinates and the coordinates given as argument.
*/
public float getDistanceSquared(int par1, int par2, int par3)
{
float f = (float)(this.x - par1);
float f1 = (float)(this.y - par2);
float f2 = (float)(this.z - par3);
return f * f + f1 * f1 + f2 * f2;
}
/**
* Return the squared distance between this coordinates and the ChunkCoordinates given as argument.
*/
public float getDistanceSquaredToWorldCoordinates(BlockCoordinates par1ChunkCoordinates)
{
return this.getDistanceSquared(par1ChunkCoordinates.x, par1ChunkCoordinates.y, par1ChunkCoordinates.z);
}
public int compareTo(Object par1Obj)
{
return this.compareWorldCoordinate((BlockCoordinates)par1Obj);
}
public void readNBT(NBTTagCompound nbt) {
this.x = nbt.getInteger("b_x");
this.y = nbt.getInteger("b_y");
this.z = nbt.getInteger("b_z");
}
public void writeNBT(NBTTagCompound nbt) {
nbt.setInteger("b_x",x);
nbt.setInteger("b_y",y);
nbt.setInteger("b_z",z);
}
}
@@ -0,0 +1,27 @@
package thaumcraft.api;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface IArchitect {
/**
* Returns a list of blocks that should be highlighted in world.
*/
public ArrayList<BlockCoordinates> getArchitectBlocks(ItemStack stack, World world,
int x, int y, int z, int side, EntityPlayer player);
/**
* which axis should be displayed.
*/
public boolean showAxis(ItemStack stack, World world, EntityPlayer player, int side, EnumAxis axis);
public enum EnumAxis {
X, // east / west
Y, // up / down
Z; // north / south
}
}
+43 -6
View File
@@ -22,6 +22,9 @@ import thaumcraft.api.crafting.InfusionEnchantmentRecipe;
import thaumcraft.api.crafting.InfusionRecipe;
import thaumcraft.api.crafting.ShapedArcaneRecipe;
import thaumcraft.api.crafting.ShapelessArcaneRecipe;
import thaumcraft.api.internal.DummyInternalMethodHandler;
import thaumcraft.api.internal.IInternalMethodHandler;
import thaumcraft.api.internal.WeightedRandomLoot;
import thaumcraft.api.research.IScanEventHandler;
import thaumcraft.api.research.ResearchCategories;
import thaumcraft.api.research.ResearchCategoryList;
@@ -62,6 +65,9 @@ public class ThaumcraftApi {
*/
public static ArrayList<Block> portableHoleBlackList = new ArrayList<Block>();
//Internal (Do not alter this unless you like pretty explosions)
//Calling methods from this will only work properly once Thaumcraft is past the FMLPreInitializationEvent phase.
public static IInternalMethodHandler internalMethods = new DummyInternalMethodHandler();
//RESEARCH/////////////////////////////////////////
public static ArrayList<IScanEventHandler> scanEventhandlers = new ArrayList<IScanEventHandler>();
@@ -323,6 +329,7 @@ public class ThaumcraftApi {
//ASPECTS////////////////////////////////////////
public static ConcurrentHashMap<List,AspectList> objectTags = new ConcurrentHashMap<List,AspectList>();
public static ConcurrentHashMap<List,int[]> groupedObjectTags = new ConcurrentHashMap<List,int[]>();
/**
* Checks to see if the passed item/block already has aspects associated with it.
@@ -370,8 +377,12 @@ public class ThaumcraftApi {
*/
public static void registerObjectTag(ItemStack item, int[] meta, AspectList aspects) {
if (aspects==null) aspects=new AspectList();
try {
objectTags.put(Arrays.asList(item.getItem(),meta), aspects);
try {
objectTags.put(Arrays.asList(item.getItem(),meta[0]), aspects);
for (int m:meta) {
groupedObjectTags.put(Arrays.asList(item.getItem(),m), meta);
}
} catch (Exception e) {}
}
@@ -456,6 +467,32 @@ public class ThaumcraftApi {
}
return 0;
}
//LOOT BAGS //////////////////////////////////////////////////////////////////////////////////////////
/**
* Used to add possible loot to treasure bags. As a reference, the weight of gold coins are 2000
* and a diamond is 50.
* The weights are the same for all loot bag types - the only difference is how many items the bag
* contains.
* @param item
* @param weight
* @param bagTypes array of which type of bag to add this loot to. Multiple types can be specified
* 0 = common, 1 = uncommon, 2 = rare
*/
public static void addLootBagItem(ItemStack item, int weight, int... bagTypes) {
if (bagTypes==null || bagTypes.length==0)
WeightedRandomLoot.lootBagCommon.add(new WeightedRandomLoot(item,weight));
else {
for (int rarity:bagTypes) {
switch(rarity) {
case 0: WeightedRandomLoot.lootBagCommon.add(new WeightedRandomLoot(item,weight)); break;
case 1: WeightedRandomLoot.lootBagUncommon.add(new WeightedRandomLoot(item,weight)); break;
case 2: WeightedRandomLoot.lootBagRare.add(new WeightedRandomLoot(item,weight)); break;
}
}
}
}
//CROPS //////////////////////////////////////////////////////////////////////////////////////////
@@ -515,9 +552,9 @@ public class ThaumcraftApi {
* in your @Mod.Init method using the "dimensionBlacklist" string message in the format "[dimension]:[level]"
* The level values are as follows:
* [0] stop all tc spawning and generation
* [1] allow ore and node generation
* [1] allow ore and node generation (and node special features)
* [2] allow mob spawning
* [3] allow ore and node gen + mob spawning
* [3] allow ore and node gen + mob spawning (and node special features)
* Example:
* FMLInterModComms.sendMessage("Thaumcraft", "dimensionBlacklist", "15:1");
*/
@@ -528,9 +565,9 @@ public class ThaumcraftApi {
* in your @Mod.Init method using the "biomeBlacklist" string message in the format "[biome id]:[level]"
* The level values are as follows:
* [0] stop all tc spawning and generation
* [1] allow ore and node generation
* [1] allow ore and node generation (and node special features)
* [2] allow mob spawning
* [3] allow ore and node gen + mob spawning
* [3] allow ore and node gen + mob spawning (and node special features)
* Example:
* FMLInterModComms.sendMessage("Thaumcraft", "biomeBlacklist", "180:2");
*/
@@ -1,13 +1,16 @@
package thaumcraft.api;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
@@ -15,7 +18,6 @@ import net.minecraftforge.oredict.OreDictionary;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import thaumcraft.api.aspects.IEssentiaTransport;
import cpw.mods.fml.common.FMLLog;
public class ThaumcraftApiHelper {
@@ -25,13 +27,37 @@ public class ThaumcraftApiHelper {
if (tag!=null)
temp2.add(tag, temp.getAmount(tag));
}
while (temp2!=null && temp2.size()>10) {
while (temp2!=null && temp2.size()>6) {
Aspect lowest = null;
int low = Integer.MAX_VALUE;
float low = Short.MAX_VALUE;
for (Aspect tag:temp2.getAspects()) {
if (tag==null) continue;
if (temp2.getAmount(tag)<low) {
low = temp2.getAmount(tag);
float ta=temp2.getAmount(tag);
if (tag.isPrimal()) {
ta *= .9f;
} else {
if (!tag.getComponents()[0].isPrimal()) {
ta *= 1.1f;
if (!tag.getComponents()[0].getComponents()[0].isPrimal()) {
ta *= 1.05f;
}
if (!tag.getComponents()[0].getComponents()[1].isPrimal()) {
ta *= 1.05f;
}
}
if (!tag.getComponents()[1].isPrimal()) {
ta *= 1.1f;
if (!tag.getComponents()[1].getComponents()[0].isPrimal()) {
ta *= 1.05f;
}
if (!tag.getComponents()[1].getComponents()[1].isPrimal()) {
ta *= 1.05f;
}
}
}
if (ta<low) {
low = ta;
lowest = tag;
}
}
@@ -49,75 +75,32 @@ public class ThaumcraftApiHelper {
return s1.getItem() == s2.getItem() && 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.lib.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.lib.research.ResearchManager method isResearchComplete");
}
return ot;
return ThaumcraftApi.internalMethods.isResearchComplete(username, researchkey);
}
public static boolean hasDiscoveredAspect(String username, Aspect aspect) {
return ThaumcraftApi.internalMethods.hasDiscoveredAspect(username, aspect);
}
public static AspectList getDiscoveredAspects(String username) {
return ThaumcraftApi.internalMethods.getDiscoveredAspects(username);
}
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;
return ThaumcraftApi.internalMethods.getStackInRowAndColumn(instance, row, column);
}
public static AspectList getObjectAspects(ItemStack is) {
AspectList ot = null;
try {
if(getObjectTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.crafting.ThaumcraftCraftingManager");
getObjectTags = fake.getMethod("getObjectTags", ItemStack.class);
}
ot = (AspectList) getObjectTags.invoke(null, is);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.crafting.ThaumcraftCraftingManager method getObjectTags");
}
return ot;
return ThaumcraftApi.internalMethods.getObjectAspects(is);
}
public static AspectList getBonusObjectTags(ItemStack is,AspectList ot) {
try {
if(getBonusTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.crafting.ThaumcraftCraftingManager");
getBonusTags = fake.getMethod("getBonusTags", ItemStack.class, AspectList.class);
}
ot = (AspectList) getBonusTags.invoke(null, is, ot);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.crafting.ThaumcraftCraftingManager method getBonusTags");
}
return ot;
return ThaumcraftApi.internalMethods.getBonusObjectTags(is, ot);
}
public static AspectList generateTags(Item item, int meta) {
try {
if(generateTags == null) {
Class fake = Class.forName("thaumcraft.common.lib.crafting.ThaumcraftCraftingManager");
generateTags = fake.getMethod("generateTags", Item.class, int.class);
}
return (AspectList) generateTags.invoke(null, item, meta);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.crafting.ThaumcraftCraftingManager method generateTags");
}
return null;
return ThaumcraftApi.internalMethods.generateTags(item, meta);
}
public static boolean containsMatch(boolean strict, ItemStack[] inputs, ItemStack... targets)
@@ -210,7 +193,7 @@ public class ThaumcraftApiHelper {
return allCompoundAspects.get(amount);
}
static Method consumeVisFromWand;
/**
* Use to subtract vis from a wand for most operations
* Wands store vis differently so "real" vis costs need to be multiplied by 100 before calling this method
@@ -224,22 +207,9 @@ public class ThaumcraftApiHelper {
*/
public static boolean consumeVisFromWand(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit, boolean crafting) {
boolean ot = false;
try {
if(consumeVisFromWand == null) {
Class fake = Class.forName("thaumcraft.common.items.wands.ItemWandCasting");
consumeVisFromWand = fake.getMethod("consumeAllVis",
ItemStack.class, EntityPlayer.class, AspectList.class, boolean.class, boolean.class);
}
ot = (Boolean) consumeVisFromWand.invoke(
consumeVisFromWand.getDeclaringClass().cast(wand.getItem()), wand, player, cost, doit, crafting);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.items.wands.ItemWandCasting method consumeAllVis");
}
return ot;
return ThaumcraftApi.internalMethods.consumeVisFromWand(wand, player, cost, doit, crafting);
}
static Method consumeVisFromWandCrafting;
/**
* Subtract vis for use by a crafting mechanic. Costs are calculated slightly
* differently and things like the frugal enchant is ignored
@@ -252,22 +222,9 @@ public class ThaumcraftApiHelper {
*/
public static boolean consumeVisFromWandCrafting(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit) {
boolean ot = false;
try {
if(consumeVisFromWandCrafting == null) {
Class fake = Class.forName("thaumcraft.common.items.wands.ItemWandCasting");
consumeVisFromWandCrafting = fake.getMethod("consumeAllVisCrafting",
ItemStack.class, EntityPlayer.class, AspectList.class, boolean.class);
}
ot = (Boolean) consumeVisFromWandCrafting.invoke(
consumeVisFromWandCrafting.getDeclaringClass().cast(wand.getItem()), wand, player, cost, doit);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.items.wands.ItemWandCasting method consumeAllVisCrafting");
}
return ot;
return ThaumcraftApi.internalMethods.consumeVisFromWandCrafting(wand, player, cost, doit);
}
static Method consumeVisFromInventory;
/**
* Subtract vis from a wand the player is carrying. Works like consumeVisFromWand in that actual vis
* costs should be multiplied by 100. The costs are handled like crafting however and things like
@@ -277,22 +234,10 @@ public class ThaumcraftApiHelper {
* @return was the vis successfully subtracted
*/
public static boolean consumeVisFromInventory(EntityPlayer player, AspectList cost) {
boolean ot = false;
try {
if(consumeVisFromInventory == null) {
Class fake = Class.forName("thaumcraft.common.items.wands.WandManager");
consumeVisFromInventory = fake.getMethod("consumeVisFromInventory",
EntityPlayer.class, AspectList.class);
}
ot = (Boolean) consumeVisFromInventory.invoke(null, player, cost);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.items.wands.WandManager method consumeVisFromInventory");
}
return ot;
return ThaumcraftApi.internalMethods.consumeVisFromInventory(player, cost);
}
static Method addWarpToPlayer;
/**
* This adds permanents or temporary warp to a player. It will automatically be synced clientside
* @param player the player using the wand
@@ -300,20 +245,9 @@ public class ThaumcraftApiHelper {
* @param temporary add temporary warp instead of permanent
*/
public static void addWarpToPlayer(EntityPlayer player, int amount, boolean temporary) {
boolean ot = false;
try {
if(addWarpToPlayer == null) {
Class fake = Class.forName("thaumcraft.common.Thaumcraft");
addWarpToPlayer = fake.getMethod("addWarpToPlayer",
EntityPlayer.class, int.class, boolean.class);
}
addWarpToPlayer.invoke(null, player, amount, temporary);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.Thaumcraft method addWarpToPlayer");
}
ThaumcraftApi.internalMethods.addWarpToPlayer(player, amount, temporary);
}
static Method addStickyWarpToPlayer;
/**
* This "sticky" warp to a player. Sticky warp is permanent warp that can be removed.
* It will automatically be synced clientside
@@ -321,16 +255,213 @@ public class ThaumcraftApiHelper {
* @param amount how much warp to add. Can have negative amounts.
*/
public static void addStickyWarpToPlayer(EntityPlayer player, int amount) {
boolean ot = false;
try {
if(addStickyWarpToPlayer == null) {
Class fake = Class.forName("thaumcraft.common.Thaumcraft");
addStickyWarpToPlayer = fake.getMethod("addStickyWarpToPlayer",
EntityPlayer.class, int.class);
ThaumcraftApi.internalMethods.addStickyWarpToPlayer(player, amount);
}
public static MovingObjectPosition rayTraceIgnoringSource(World world, Vec3 v1, Vec3 v2,
boolean bool1, boolean bool2, boolean bool3)
{
if (!Double.isNaN(v1.xCoord) && !Double.isNaN(v1.yCoord) && !Double.isNaN(v1.zCoord))
{
if (!Double.isNaN(v2.xCoord) && !Double.isNaN(v2.yCoord) && !Double.isNaN(v2.zCoord))
{
int i = MathHelper.floor_double(v2.xCoord);
int j = MathHelper.floor_double(v2.yCoord);
int k = MathHelper.floor_double(v2.zCoord);
int l = MathHelper.floor_double(v1.xCoord);
int i1 = MathHelper.floor_double(v1.yCoord);
int j1 = MathHelper.floor_double(v1.zCoord);
Block block = world.getBlock(l, i1, j1);
int k1 = world.getBlockMetadata(l, i1, j1);
MovingObjectPosition movingobjectposition2 = null;
k1 = 200;
while (k1-- >= 0)
{
if (Double.isNaN(v1.xCoord) || Double.isNaN(v1.yCoord) || Double.isNaN(v1.zCoord))
{
return null;
}
if (l == i && i1 == j && j1 == k)
{
continue;
}
boolean flag6 = true;
boolean flag3 = true;
boolean flag4 = true;
double d0 = 999.0D;
double d1 = 999.0D;
double d2 = 999.0D;
if (i > l)
{
d0 = (double)l + 1.0D;
}
else if (i < l)
{
d0 = (double)l + 0.0D;
}
else
{
flag6 = false;
}
if (j > i1)
{
d1 = (double)i1 + 1.0D;
}
else if (j < i1)
{
d1 = (double)i1 + 0.0D;
}
else
{
flag3 = false;
}
if (k > j1)
{
d2 = (double)j1 + 1.0D;
}
else if (k < j1)
{
d2 = (double)j1 + 0.0D;
}
else
{
flag4 = false;
}
double d3 = 999.0D;
double d4 = 999.0D;
double d5 = 999.0D;
double d6 = v2.xCoord - v1.xCoord;
double d7 = v2.yCoord - v1.yCoord;
double d8 = v2.zCoord - v1.zCoord;
if (flag6)
{
d3 = (d0 - v1.xCoord) / d6;
}
if (flag3)
{
d4 = (d1 - v1.yCoord) / d7;
}
if (flag4)
{
d5 = (d2 - v1.zCoord) / d8;
}
boolean flag5 = false;
byte b0;
if (d3 < d4 && d3 < d5)
{
if (i > l)
{
b0 = 4;
}
else
{
b0 = 5;
}
v1.xCoord = d0;
v1.yCoord += d7 * d3;
v1.zCoord += d8 * d3;
}
else if (d4 < d5)
{
if (j > i1)
{
b0 = 0;
}
else
{
b0 = 1;
}
v1.xCoord += d6 * d4;
v1.yCoord = d1;
v1.zCoord += d8 * d4;
}
else
{
if (k > j1)
{
b0 = 2;
}
else
{
b0 = 3;
}
v1.xCoord += d6 * d5;
v1.yCoord += d7 * d5;
v1.zCoord = d2;
}
Vec3 vec32 = Vec3.createVectorHelper(v1.xCoord, v1.yCoord, v1.zCoord);
l = (int)(vec32.xCoord = (double)MathHelper.floor_double(v1.xCoord));
if (b0 == 5)
{
--l;
++vec32.xCoord;
}
i1 = (int)(vec32.yCoord = (double)MathHelper.floor_double(v1.yCoord));
if (b0 == 1)
{
--i1;
++vec32.yCoord;
}
j1 = (int)(vec32.zCoord = (double)MathHelper.floor_double(v1.zCoord));
if (b0 == 3)
{
--j1;
++vec32.zCoord;
}
Block block1 = world.getBlock(l, i1, j1);
int l1 = world.getBlockMetadata(l, i1, j1);
if (!bool2 || block1.getCollisionBoundingBoxFromPool(world, l, i1, j1) != null)
{
if (block1.canCollideCheck(l1, bool1))
{
MovingObjectPosition movingobjectposition1 = block1.collisionRayTrace(world, l, i1, j1, v1, v2);
if (movingobjectposition1 != null)
{
return movingobjectposition1;
}
}
else
{
movingobjectposition2 = new MovingObjectPosition(l, i1, j1, b0, v1, false);
}
}
}
return bool3 ? movingobjectposition2 : null;
}
addStickyWarpToPlayer.invoke(null, player, amount);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.Thaumcraft method addStickyWarpToPlayer");
else
{
return null;
}
}
else
{
return null;
}
}
}
@@ -181,14 +181,14 @@ public class Aspect {
public static final Aspect BEAST = new Aspect("bestia",0x9f6409, new Aspect[] {MOTION, LIFE});
public static final Aspect FLESH = new Aspect("corpus",0xee478d, new Aspect[] {DEATH, BEAST});
public static final Aspect UNDEAD = new Aspect("exanimis",0x3a4000, new Aspect[] {MOTION, DEATH});
public static final Aspect MIND = new Aspect("cognitio",0xffc2b3, new Aspect[] {EARTH, SOUL});
public static final Aspect MIND = new Aspect("cognitio",0xffc2b3, new Aspect[] {FIRE, SOUL});
public static final Aspect SENSES = new Aspect("sensus",0x0fd9ff, new Aspect[] {AIR, SOUL});
public static final Aspect MAN = new Aspect("humanus",0xffd7c0, new Aspect[] {BEAST, MIND});
public static final Aspect CROP = new Aspect("messis",0xe1b371, new Aspect[] {PLANT, MAN});
public static final Aspect MINE = new Aspect("perfodio",0xdcd2d8, new Aspect[] {MAN, EARTH});
public static final Aspect TOOL = new Aspect("instrumentum",0x4040ee, new Aspect[] {MAN, ORDER});
public static final Aspect HARVEST = new Aspect("meto",0xeead82, new Aspect[] {CROP, TOOL});
public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, ENTROPY});
public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, FIRE});
public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, EARTH});
public static final Aspect HUNGER = new Aspect("fames",0x9a0305, new Aspect[] {LIFE, VOID});
public static final Aspect GREED = new Aspect("lucrum",0xe6be44, new Aspect[] {MAN, HUNGER});
@@ -84,7 +84,7 @@ public class AspectList implements Serializable {
*/
public Aspect[] getAspectsSorted() {
try {
Aspect[] out = aspects.keySet().toArray(new Aspect[1]);
Aspect[] out = aspects.keySet().toArray(new Aspect[]{});
boolean change=false;
do {
change=false;
@@ -215,6 +215,18 @@ public class AspectList implements Serializable {
return this;
}
public AspectList add(AspectList in) {
for (Aspect a:in.getAspects())
this.add(a, in.getAmount(a));
return this;
}
public AspectList merge(AspectList in) {
for (Aspect a:in.getAspects())
this.merge(a, in.getAmount(a));
return this;
}
/**
* Reads the list of aspects from nbt
* @param nbttagcompound
@@ -69,13 +69,16 @@ public class InfusionRecipe
return ii.size()==0?true:false;
}
protected boolean areItemStacksEqual(ItemStack stack0, ItemStack stack1, boolean fuzzy)
public static boolean areItemStacksEqual(ItemStack stack0, ItemStack stack1, boolean fuzzy)
{
if (stack0==null && stack1!=null) return false;
if (stack0!=null && stack1==null) return false;
if (stack0==null && stack1==null) return true;
boolean t1=ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(stack0, stack1);
//nbt
boolean t1=ThaumcraftApiHelper.areItemStackTagsEqualForCrafting(stack0, stack1);
if (!t1) return false;
if (fuzzy) {
int od = OreDictionary.getOreID(stack0);
if (od!=-1) {
@@ -84,7 +87,12 @@ public class InfusionRecipe
return true;
}
}
return stack0.getItem() != stack1.getItem() ? false : (stack0.getItemDamage() != stack1.getItemDamage() ? false : stack0.stackSize <= stack0.getMaxStackSize() );
//damage
boolean damage = stack0.getItemDamage() == stack1.getItemDamage() ||
stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE;
return stack0.getItem() != stack1.getItem() ? false : (!damage ? false : stack0.stackSize <= stack0.getMaxStackSize() );
}
public Object getRecipeOutput() {
@@ -0,0 +1,5 @@
package thaumcraft.api.entities;
public interface IEldritchMob {
}
@@ -0,0 +1,78 @@
package thaumcraft.api.internal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class DummyInternalMethodHandler implements IInternalMethodHandler {
@Override
public void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color) {
}
@Override
public boolean isResearchComplete(String username, String researchkey) {
return false;
}
@Override
public boolean hasDiscoveredAspect(String username, Aspect aspect) {
return false;
}
@Override
public AspectList getDiscoveredAspects(String username) {
return null;
}
@Override
public ItemStack getStackInRowAndColumn(Object instance, int row, int column) {
return null;
}
@Override
public AspectList getObjectAspects(ItemStack is) {
return null;
}
@Override
public AspectList getBonusObjectTags(ItemStack is, AspectList ot) {
return null;
}
@Override
public AspectList generateTags(Item item, int meta) {
return null;
}
@Override
public boolean consumeVisFromWand(ItemStack wand, EntityPlayer player,
AspectList cost, boolean doit, boolean crafting) {
return false;
}
@Override
public boolean consumeVisFromWandCrafting(ItemStack wand,
EntityPlayer player, AspectList cost, boolean doit) {
return false;
}
@Override
public boolean consumeVisFromInventory(EntityPlayer player, AspectList cost) {
return false;
}
@Override
public void addWarpToPlayer(EntityPlayer player, int amount, boolean temporary) {
}
@Override
public void addStickyWarpToPlayer(EntityPlayer player, int amount) {
}
}
@@ -0,0 +1,25 @@
package thaumcraft.api.internal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public interface IInternalMethodHandler {
public void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color);
public boolean isResearchComplete(String username, String researchkey);
public ItemStack getStackInRowAndColumn(Object instance, int row, int column);
public AspectList getObjectAspects(ItemStack is);
public AspectList getBonusObjectTags(ItemStack is,AspectList ot);
public AspectList generateTags(Item item, int meta);
public boolean consumeVisFromWand(ItemStack wand, EntityPlayer player, AspectList cost, boolean doit, boolean crafting);
public boolean consumeVisFromWandCrafting(ItemStack wand,EntityPlayer player, AspectList cost, boolean doit);
public boolean consumeVisFromInventory(EntityPlayer player, AspectList cost);
public void addWarpToPlayer(EntityPlayer player, int amount,boolean temporary);
public void addStickyWarpToPlayer(EntityPlayer player, int amount);
public boolean hasDiscoveredAspect(String username, Aspect aspect);
public AspectList getDiscoveredAspects(String username);
}
@@ -0,0 +1,24 @@
package thaumcraft.api.internal;
import java.util.ArrayList;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
public class WeightedRandomLoot extends WeightedRandom.Item {
/** The Item/Block ID to generate in the bag. */
public ItemStack item;
public WeightedRandomLoot(ItemStack stack, int weight)
{
super(weight);
this.item = stack;
}
public static ArrayList<WeightedRandomLoot> lootBagCommon = new ArrayList<WeightedRandomLoot>();
public static ArrayList<WeightedRandomLoot> lootBagUncommon = new ArrayList<WeightedRandomLoot>();
public static ArrayList<WeightedRandomLoot> lootBagRare = new ArrayList<WeightedRandomLoot>();
}
@@ -1,4 +1,4 @@
@API(owner = "Thaumcraft", apiVersion = "4.2.0.0", provides = "Thaumcraft|API")
@API(owner = "Thaumcraft", apiVersion = "4.2.2.0", provides = "Thaumcraft|API")
package thaumcraft.api;
import cpw.mods.fml.common.API;
@@ -91,8 +91,7 @@ public class ResearchItem
*/
private boolean isVirtual;
@Deprecated
private boolean isLost;
/**
* Concealed research does not display in the thaumonomicon until parent researches are discovered.
@@ -104,6 +103,11 @@ public class ResearchItem
*/
private boolean isHidden;
/**
* This is the same as isHidden, except it cannot be discovered with knowledge fragments, only scanning.
*/
private boolean isLost;
/**
* These research items will automatically unlock for all players on game start
*/
@@ -179,7 +183,6 @@ public class ResearchItem
return this;
}
@Deprecated
public ResearchItem setLost()
{
this.isLost = true;
@@ -290,7 +293,6 @@ public class ResearchItem
return this.isStub;
}
@Deprecated
public boolean isLost()
{
return this.isLost;
@@ -136,7 +136,7 @@ public abstract class TileVisNode extends TileThaumcraft {
//check for changes
if (!nodeRefresh && children.size()>0) {
for (WeakReference<TileVisNode> n:children) {
if (n==null || n.get()==null) {
if (n==null || n.get()==null || !VisNetHandler.canNodeBeSeen(this, n.get())) {
nodeRefresh=true;
break;
}
@@ -1,14 +1,17 @@
package thaumcraft.api.visnet;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import thaumcraft.api.ThaumcraftApi;
import thaumcraft.api.ThaumcraftApiHelper;
import thaumcraft.api.WorldCoordinates;
import thaumcraft.api.aspects.Aspect;
import cpw.mods.fml.common.FMLLog;
public class VisNetHandler {
@@ -59,17 +62,8 @@ public class VisNetHandler {
return drainedAmount;
}
static Method generateVisEffect;
public static void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color) {
try {
if(generateVisEffect == null) {
Class fake = Class.forName("thaumcraft.common.lib.Utils");
generateVisEffect = fake.getMethod("generateVisEffect", int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class);
}
generateVisEffect.invoke(null, dim, x,y,z,x2,y2,z2,color);
} catch(Exception ex) {
FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.Utils method generateVisEffect");
}
ThaumcraftApi.internalMethods.generateVisEffect(dim, x, y, z, x2, y2, z2, color);
}
public static HashMap<Integer, HashMap<WorldCoordinates, WeakReference<TileVisNode>>> sources = new HashMap<Integer, HashMap<WorldCoordinates, WeakReference<TileVisNode>>>();
@@ -114,17 +108,21 @@ public class VisNetHandler {
if (r > 0) {
nearby.add(new Object[] { source, r - vn.getRange() * 2 });
}
nearby = findClosestNodes(vn, source, nearby);
cache.clear();
}
float dist = Float.MAX_VALUE;
TileVisNode closest = null;
if (nearby.size() > 0) {
for (Object[] o : nearby) {
if ((Float) o[1] < dist) {// && canNodeBeSeen(vn,(TileVisNode)
// o[0])) {
if ((Float) o[1] < dist &&
(vn.getAttunement() == -1 || ((TileVisNode) o[0]).getAttunement() == -1 ||
vn.getAttunement() == ((TileVisNode) o[0]).getAttunement())//) {
&& canNodeBeSeen(vn,(TileVisNode)o[0])) {
dist = (Float) o[1];
closest = (TileVisNode) o[0];
closest = (TileVisNode) o[0];
}
}
}
@@ -137,26 +135,24 @@ public class VisNetHandler {
return null;
}
static ArrayList<WorldCoordinates> cache = new ArrayList<WorldCoordinates>();
public static ArrayList<Object[]> findClosestNodes(TileVisNode target,
TileVisNode root, ArrayList<Object[]> in) {
TileVisNode closestChild = null;
TileVisNode parent, ArrayList<Object[]> in) {
if (cache.size() > 512 || cache.contains(new WorldCoordinates(parent))) return in;
cache.add(new WorldCoordinates(parent));
for (WeakReference<TileVisNode> childWR : parent.getChildren()) {
TileVisNode child = childWR.get();
for (WeakReference<TileVisNode> child : root.getChildren()) {
TileVisNode n = child.get();
if (n != null
&& !n.equals(target)
&& !n.equals(root)
&& (target.getAttunement() == -1 || n.getAttunement() == -1 || n
.getAttunement() == target.getAttunement())) {
float r2 = inRange(n.getWorldObj(), n.getLocation(),
if (child != null && !child.equals(target) && !child.equals(parent)) {
float r2 = inRange(child.getWorldObj(), child.getLocation(),
target.getLocation(), target.getRange());
if (r2 > 0) {
in.add(new Object[] { n, r2 });
in.add(new Object[] { child, r2 });
}
in = findClosestNodes(target, n, in);
in = findClosestNodes(target, child, in);
}
}
return in;
@@ -238,20 +234,15 @@ public class VisNetHandler {
return list;
}
// public static boolean canNodeBeSeen(TileVisNode source,TileVisNode
// target)
// {
// double d = Math.sqrt(source.getDistanceFrom(target.xCoord, target.yCoord,
// target.zCoord));
// double xd = (source.xCoord-target.xCoord) / d;
// double yd = (source.yCoord-target.yCoord) / d;
// double zd = (source.zCoord-target.zCoord) / d;
// return source.getWorldObj().rayTraceBlocks(
// Vec3.createVectorHelper(source.xCoord-xd+.5+.5, source.yCoord-yd,
// source.zCoord-zd),
// Vec3.createVectorHelper(target.xCoord+.5, target.yCoord+.5,
// target.zCoord+.5)) == null;
// }
public static boolean canNodeBeSeen(TileVisNode source,TileVisNode target)
{
MovingObjectPosition mop = ThaumcraftApiHelper.rayTraceIgnoringSource(source.getWorldObj(),
Vec3.createVectorHelper(source.xCoord+.5, source.yCoord+.5,source.zCoord+.5),
Vec3.createVectorHelper(target.xCoord+.5, target.yCoord+.5,target.zCoord+.5),
false, true, false);
return mop == null || (mop.typeOfHit==MovingObjectType.BLOCK &&
mop.blockX==target.xCoord && mop.blockY==target.yCoord && mop.blockZ==target.zCoord);
}
// public static HashMap<WorldCoordinates,WeakReference<TileVisNode>>
// noderef = new HashMap<WorldCoordinates,WeakReference<TileVisNode>>();
@@ -0,0 +1,114 @@
package thaumcraft.api.wands;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.apache.logging.log4j.LogManager;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
public class FocusUpgradeType {
public static FocusUpgradeType[] types = new FocusUpgradeType[20];
public short id;
public ResourceLocation icon;
public String name;
public String text;
/**
* What aspects are used to calculate the cost of this upgrade. The amounts given is ignored, just the type is used for the calculation.
*/
public AspectList aspects;
public FocusUpgradeType(int id, ResourceLocation icon, String name, String text, AspectList aspects) {
this.id = (short) id;
this.icon = icon;
this.name = name;
this.text = text;
this.aspects = aspects;
if (id<types.length && types[id]!=null) {
LogManager.getLogger("THAUMCRAFT").fatal("Focus Upgrade id "+id+" already occupied. Ignoring.");
return;
}
// allocate space
if (id>=types.length) {
FocusUpgradeType[] temp = new FocusUpgradeType[id+1];
System.arraycopy(types, 0, temp, 0, id);
types = temp;
}
types[id] = this;
}
public String getLocalizedName() {
return StatCollector.translateToLocal(name);
}
public String getLocalizedText() {
return StatCollector.translateToLocal(text);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FocusUpgradeType) {
return this.id == ((FocusUpgradeType)obj).id;
} else return false;
}
// basic upgrade types
public static FocusUpgradeType potency = new FocusUpgradeType( 0,
new ResourceLocation("thaumcraft", "textures/foci/potency.png"),
"focus.upgrade.potency.name","focus.upgrade.potency.text",
new AspectList().add(Aspect.WEAPON,1));
public static FocusUpgradeType frugal = new FocusUpgradeType( 1,
new ResourceLocation("thaumcraft", "textures/foci/frugal.png"),
"focus.upgrade.frugal.name","focus.upgrade.frugal.text",
new AspectList().add(Aspect.HUNGER,1));
public static FocusUpgradeType treasure = new FocusUpgradeType( 2,
new ResourceLocation("thaumcraft", "textures/foci/treasure.png"),
"focus.upgrade.treasure.name","focus.upgrade.treasure.text",
new AspectList().add(Aspect.GREED,1));
public static FocusUpgradeType enlarge = new FocusUpgradeType( 3,
new ResourceLocation("thaumcraft", "textures/foci/enlarge.png"),
"focus.upgrade.enlarge.name","focus.upgrade.enlarge.text",
new AspectList().add(Aspect.TRAVEL,1));
public static FocusUpgradeType alchemistsfire = new FocusUpgradeType( 4,
new ResourceLocation("thaumcraft", "textures/foci/alchemistsfire.png"),
"focus.upgrade.alchemistsfire.name","focus.upgrade.alchemistsfire.text",
new AspectList().add(Aspect.ENERGY,1).add(Aspect.SLIME,1));
public static FocusUpgradeType alchemistsfrost = new FocusUpgradeType( 5,
new ResourceLocation("thaumcraft", "textures/foci/alchemistsfrost.png"),
"focus.upgrade.alchemistsfrost.name","focus.upgrade.alchemistsfrost.text",
new AspectList().add(Aspect.COLD,1).add(Aspect.TRAP,1));
public static FocusUpgradeType architect = new FocusUpgradeType( 6,
new ResourceLocation("thaumcraft", "textures/foci/architect.png"),
"focus.upgrade.architect.name","focus.upgrade.architect.text",
new AspectList().add(Aspect.CRAFT,1));
public static FocusUpgradeType extend = new FocusUpgradeType( 7,
new ResourceLocation("thaumcraft", "textures/foci/extend.png"),
"focus.upgrade.extend.name","focus.upgrade.extend.text",
new AspectList().add(Aspect.EXCHANGE,1));
public static FocusUpgradeType silktouch = new FocusUpgradeType( 8,
new ResourceLocation("thaumcraft", "textures/foci/silktouch.png"),
"focus.upgrade.silktouch.name","focus.upgrade.silktouch.text",
new AspectList().add(Aspect.GREED,1));
}
@@ -1,64 +0,0 @@
package thaumcraft.api.wands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import thaumcraft.api.aspects.AspectList;
public interface IWandFocus {
public enum WandFocusAnimation {
WAVE, CHARGE;
}
/**
* @return The color the focus should be changed to.
*/
public int getFocusColor();
/**
* @return An icon that will be drawn as a block inside the focus "block".
*/
IIcon getFocusDepthLayerIcon();
public IIcon getOrnament();
public WandFocusAnimation getAnimation();
/**
* Gets the amount of vis used per aspect per click or tick. This cost is actually listed as
* a hundredth of a single point of vis, so a cost of 100 will equal one vis per tick/click.
* It is returned as an AspectList to allow for multiple vis types in different ratios.
*/
public AspectList getVisCost();
public boolean isVisCostPerTick();
public ItemStack onFocusRightClick(ItemStack itemstack, World world, EntityPlayer player, MovingObjectPosition movingobjectposition);
public void onUsingFocusTick(ItemStack itemstack, EntityPlayer player, int count);
public void onPlayerStoppedUsingFocus(ItemStack itemstack, World world, EntityPlayer player, int count);
/**
* Helper method to determine in what order foci should be iterated through when
* the user presses the 'change focus' keybinding.
* @return a string of characters that foci will be sorted against.
* For example AA00 will be placed before FG12
* <br>As a guide build the sort string from two alphanumeric characters followed by
* two numeric characters based on... whatever.
*/
public String getSortingHelper(ItemStack itemstack);
boolean onFocusBlockStartBreak(ItemStack itemstack, int x, int y, int z, EntityPlayer player);
public boolean acceptsEnchant(int id);
}
@@ -1,25 +1,26 @@
package thaumcraft.api.wands;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import thaumcraft.api.ThaumcraftApi;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ItemFocusBasic extends Item implements IWandFocus {
public abstract class ItemFocusBasic extends Item {
public ItemFocusBasic ()
{
@@ -37,130 +38,222 @@ public class ItemFocusBasic extends Item implements IWandFocus {
return icon;
}
@Override
public boolean isItemTool(ItemStack par1ItemStack)
{
return true;
}
@Override
public boolean isDamageable() {
return true;
return false;
}
@Override
public void addInformation(ItemStack stack,EntityPlayer player, List list, boolean par4) {
AspectList al = this.getVisCost();
AspectList al = this.getVisCost(stack);
if (al!=null && al.size()>0) {
list.add(StatCollector.translateToLocal(isVisCostPerTick()?"item.Focus.cost2":"item.Focus.cost1"));
list.add(StatCollector.translateToLocal(isVisCostPerTick(stack)?"item.Focus.cost2":"item.Focus.cost1"));
for (Aspect aspect:al.getAspectsSorted()) {
DecimalFormat myFormatter = new DecimalFormat("#####.##");
String amount = myFormatter.format(al.getAmount(aspect)/100f);
list.add(" \u00A7"+aspect.getChatcolor()+aspect.getName()+"\u00A7r x "+ amount);
list.add(" \u00A7"+aspect.getChatcolor()+aspect.getName()+"\u00A7r x "+ amount);
}
}
addFocusInformation(stack,player,list,par4);
}
public void addFocusInformation(ItemStack focusstack,EntityPlayer player, List list, boolean par4) {
LinkedHashMap<Short, Integer> map = new LinkedHashMap<Short, Integer>();
for (short id:this.getAppliedUpgrades(focusstack)) {
if (id>=0) {
int amt = 1;
if (map.containsKey(id)) {
amt = map.get(id) + 1;
}
map.put(id, amt);
}
}
for (Short id:map.keySet()) {
list.add(EnumChatFormatting.DARK_PURPLE +FocusUpgradeType.types[id].getLocalizedName()+
(map.get(id)>1?" "+StatCollector.translateToLocal("enchantment.level." + map.get(id)):""));
}
}
@Override
public int getItemEnchantability() {
return 5;
/**
* Purely for display on the focus tooltip (see addInformation method above)
*/
public boolean isVisCostPerTick(ItemStack focusstack) {
return false;
}
@Override
public EnumRarity getRarity(ItemStack itemstack)
public EnumRarity getRarity(ItemStack focusstack)
{
return EnumRarity.rare;
}
}
/**
* What color will the focus orb be rendered on the held wand
*/
public abstract int getFocusColor(ItemStack focusstack);
@Override
public int getFocusColor() {
// TODO Auto-generated method stub
return 0;
}
@Override
public AspectList getVisCost() {
// TODO Auto-generated method stub
return null;
}
@Override
public ItemStack onFocusRightClick(ItemStack itemstack, World world,
EntityPlayer player, MovingObjectPosition movingobjectposition) {
/**
* Does the focus have ornamentation like the focus of the nine hells. Ornamentation is a standard icon rendered in a cross around the focus
*/
public IIcon getOrnament(ItemStack focusstack) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onUsingFocusTick(ItemStack itemstack, EntityPlayer player,
int count) {
// TODO Auto-generated method stub
/**
* An icon to be rendered inside the focus itself
*/
public IIcon getFocusDepthLayerIcon(ItemStack focusstack) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onPlayerStoppedUsingFocus(ItemStack itemstack, World world,
EntityPlayer player, int count) {
// TODO Auto-generated method stub
public enum WandFocusAnimation {
WAVE, CHARGE;
}
public WandFocusAnimation getAnimation(ItemStack focusstack) {
return WandFocusAnimation.WAVE;
}
/**
* Just insert two alphanumeric characters before this string in your focus item class
*/
@Override
public String getSortingHelper(ItemStack itemstack) {
Map<Integer,Integer> ench = EnchantmentHelper.getEnchantments(itemstack);
public String getSortingHelper(ItemStack focusstack) {
String out="";
for (Integer lvl:ench.values()) {
out = out + lvl + "";
for (short id:this.getAppliedUpgrades(focusstack)) {
out = out + id;
}
return out;
}
/**
* How much vis does this focus consume per activation.
*/
public abstract AspectList getVisCost(ItemStack focusstack);
/**
* This returns how many milliseconds must pass before the focus can be activated again.
*/
public int getActivationCooldown(ItemStack focusstack) {
return 0;
}
/**
* Used by foci like equal trade to determine their area in artchitect mode
*/
public int getMaxAreaSize(ItemStack focusstack) {
return 1;
}
/**
* What upgrades can be applied to this focus for ranks 1 to 5
*/
public abstract FocusUpgradeType[] getPossibleUpgradesByRank(ItemStack focusstack, int rank);
/**
* What upgrades does the focus currently have
*/
public short[] getAppliedUpgrades(ItemStack focusstack) {
short[] l = new short[] {-1,-1,-1,-1,-1};
NBTTagList nbttaglist = getFocusUpgradeTagList(focusstack);
if (nbttaglist == null)
{
return l;
}
else
{
for (int j = 0; j < nbttaglist.tagCount(); ++j)
{
if (j>=5) break;
l[j] = nbttaglist.getCompoundTagAt(j).getShort("id");
}
@Override
public boolean isVisCostPerTick() {
return false;
return l;
}
}
public boolean applyUpgrade(ItemStack focusstack, FocusUpgradeType type, int rank) {
short[] upgrades = getAppliedUpgrades(focusstack);
if (upgrades[rank-1]!=-1 || rank<1 || rank>5) {
return false;
}
upgrades[rank-1] = type.id;
setFocusUpgradeTagList(focusstack, upgrades);
return true;
}
/**
* Use this method to define custom logic about which upgrades can be applied. This can be used to set up upgrade "trees"
* that make certain upgrades available only when others are unlocked first, when certain research is completed, or similar logic.
*
*/
public boolean canApplyUpgrade(ItemStack focusstack, EntityPlayer player, FocusUpgradeType type, int rank) {
return true;
}
@Override
public IIcon getOrnament() {
/**
* Does this focus have the passed upgrade type
*/
public boolean isUpgradedWith(ItemStack focusstack, FocusUpgradeType focusUpgradetype) {
return getUpgradeLevel(focusstack,focusUpgradetype)>0;
}
/**
* What level is the passed upgrade type on the focus. If it is not present it returns 0
*/
public int getUpgradeLevel(ItemStack focusstack, FocusUpgradeType focusUpgradetype) {
short[] list = getAppliedUpgrades(focusstack);
int level=0;
for (short id:list) {
if (id == focusUpgradetype.id)
{
level++;
}
}
return level;
}
public ItemStack onFocusRightClick(ItemStack wandstack, World world,EntityPlayer player, MovingObjectPosition movingobjectposition) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onFocusBlockStartBreak(ItemStack itemstack, int x, int y,
int z, EntityPlayer player) {
public void onUsingFocusTick(ItemStack wandstack, EntityPlayer player,int count) {
// TODO Auto-generated method stub
}
public void onPlayerStoppedUsingFocus(ItemStack wandstack, World world, EntityPlayer player, int count) {
// TODO Auto-generated method stub
}
public boolean onFocusBlockStartBreak(ItemStack wandstack, int x, int y,int z, EntityPlayer player) {
// TODO Auto-generated method stub
return false;
}
@Override
public WandFocusAnimation getAnimation() {
return WandFocusAnimation.WAVE;
}
@Override
public IIcon getFocusDepthLayerIcon() {
// TODO Auto-generated method stub
return null;
}
/**
* @see thaumcraft.api.wands.IWandFocus#acceptsEnchant(int)
* By default fortune is off for all wands
**/
@Override
public boolean acceptsEnchant(int id) {
if (id==ThaumcraftApi.enchantFrugal||
id==ThaumcraftApi.enchantPotency) return true;
return false;
}
/**
* Internal helper methods
*/
private NBTTagList getFocusUpgradeTagList(ItemStack focusstack)
{
return focusstack.stackTagCompound == null ? null : focusstack.stackTagCompound.getTagList("upgrade", 10);
}
private void setFocusUpgradeTagList(ItemStack focusstack, short[] upgrades) {
if (!focusstack.hasTagCompound())
focusstack.setTagCompound(new NBTTagCompound());
NBTTagCompound nbttagcompound = focusstack.getTagCompound();
NBTTagList tlist = new NBTTagList();
nbttagcompound.setTag("upgrade", tlist);
for (short id : upgrades) {
NBTTagCompound f = new NBTTagCompound();
f.setShort("id", id);
tlist.appendTag(f);
}
}
}