diff --git a/build.properties b/build.properties index 7e3948b..cdb885d 100644 --- a/build.properties +++ b/build.properties @@ -1,3 +1,3 @@ minecraft_version=1.7.10 forge_version=10.13.1.1225 -mod_version=0.55 \ No newline at end of file +mod_version=0.551 \ No newline at end of file diff --git a/src/api/java/thaumcraft/api/BlockCoordinates.java b/src/api/java/thaumcraft/api/BlockCoordinates.java new file mode 100644 index 0000000..27a28f8 --- /dev/null +++ b/src/api/java/thaumcraft/api/BlockCoordinates.java @@ -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); + } + +} diff --git a/src/api/java/thaumcraft/api/IArchitect.java b/src/api/java/thaumcraft/api/IArchitect.java new file mode 100644 index 0000000..c733af5 --- /dev/null +++ b/src/api/java/thaumcraft/api/IArchitect.java @@ -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 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 + } +} diff --git a/src/api/java/thaumcraft/api/ThaumcraftApi.java b/src/api/java/thaumcraft/api/ThaumcraftApi.java index 0d0a672..eeb9f6b 100644 --- a/src/api/java/thaumcraft/api/ThaumcraftApi.java +++ b/src/api/java/thaumcraft/api/ThaumcraftApi.java @@ -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 portableHoleBlackList = new ArrayList(); + //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 scanEventhandlers = new ArrayList(); @@ -323,6 +329,7 @@ public class ThaumcraftApi { //ASPECTS//////////////////////////////////////// public static ConcurrentHashMap objectTags = new ConcurrentHashMap(); + public static ConcurrentHashMap groupedObjectTags = new ConcurrentHashMap(); /** * 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"); */ diff --git a/src/api/java/thaumcraft/api/ThaumcraftApiHelper.java b/src/api/java/thaumcraft/api/ThaumcraftApiHelper.java index 8487a20..77d5588 100644 --- a/src/api/java/thaumcraft/api/ThaumcraftApiHelper.java +++ b/src/api/java/thaumcraft/api/ThaumcraftApiHelper.java @@ -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)= 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; } } } diff --git a/src/api/java/thaumcraft/api/aspects/Aspect.java b/src/api/java/thaumcraft/api/aspects/Aspect.java index 3c33a4a..0ea13f5 100644 --- a/src/api/java/thaumcraft/api/aspects/Aspect.java +++ b/src/api/java/thaumcraft/api/aspects/Aspect.java @@ -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}); diff --git a/src/api/java/thaumcraft/api/aspects/AspectList.java b/src/api/java/thaumcraft/api/aspects/AspectList.java index 6fcfe98..b578141 100644 --- a/src/api/java/thaumcraft/api/aspects/AspectList.java +++ b/src/api/java/thaumcraft/api/aspects/AspectList.java @@ -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 diff --git a/src/api/java/thaumcraft/api/crafting/InfusionRecipe.java b/src/api/java/thaumcraft/api/crafting/InfusionRecipe.java index 491db3d..573dbbb 100644 --- a/src/api/java/thaumcraft/api/crafting/InfusionRecipe.java +++ b/src/api/java/thaumcraft/api/crafting/InfusionRecipe.java @@ -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() { diff --git a/src/api/java/thaumcraft/api/entities/IEldritchMob.java b/src/api/java/thaumcraft/api/entities/IEldritchMob.java new file mode 100644 index 0000000..79fc75b --- /dev/null +++ b/src/api/java/thaumcraft/api/entities/IEldritchMob.java @@ -0,0 +1,5 @@ +package thaumcraft.api.entities; + +public interface IEldritchMob { + +} diff --git a/src/api/java/thaumcraft/api/internal/DummyInternalMethodHandler.java b/src/api/java/thaumcraft/api/internal/DummyInternalMethodHandler.java new file mode 100644 index 0000000..9af8c30 --- /dev/null +++ b/src/api/java/thaumcraft/api/internal/DummyInternalMethodHandler.java @@ -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) { + } + + + +} diff --git a/src/api/java/thaumcraft/api/internal/IInternalMethodHandler.java b/src/api/java/thaumcraft/api/internal/IInternalMethodHandler.java new file mode 100644 index 0000000..73fce66 --- /dev/null +++ b/src/api/java/thaumcraft/api/internal/IInternalMethodHandler.java @@ -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); + +} diff --git a/src/api/java/thaumcraft/api/internal/WeightedRandomLoot.java b/src/api/java/thaumcraft/api/internal/WeightedRandomLoot.java new file mode 100644 index 0000000..4ac6ee7 --- /dev/null +++ b/src/api/java/thaumcraft/api/internal/WeightedRandomLoot.java @@ -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 lootBagCommon = new ArrayList(); + public static ArrayList lootBagUncommon = new ArrayList(); + public static ArrayList lootBagRare = new ArrayList(); + +} diff --git a/src/api/java/thaumcraft/api/package-info.java b/src/api/java/thaumcraft/api/package-info.java index 0de3926..cceaf89 100644 --- a/src/api/java/thaumcraft/api/package-info.java +++ b/src/api/java/thaumcraft/api/package-info.java @@ -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; diff --git a/src/api/java/thaumcraft/api/research/ResearchItem.java b/src/api/java/thaumcraft/api/research/ResearchItem.java index 55b3820..1d5fd8b 100644 --- a/src/api/java/thaumcraft/api/research/ResearchItem.java +++ b/src/api/java/thaumcraft/api/research/ResearchItem.java @@ -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; diff --git a/src/api/java/thaumcraft/api/visnet/TileVisNode.java b/src/api/java/thaumcraft/api/visnet/TileVisNode.java index 84b1400..204879e 100644 --- a/src/api/java/thaumcraft/api/visnet/TileVisNode.java +++ b/src/api/java/thaumcraft/api/visnet/TileVisNode.java @@ -136,7 +136,7 @@ public abstract class TileVisNode extends TileThaumcraft { //check for changes if (!nodeRefresh && children.size()>0) { for (WeakReference n:children) { - if (n==null || n.get()==null) { + if (n==null || n.get()==null || !VisNetHandler.canNodeBeSeen(this, n.get())) { nodeRefresh=true; break; } diff --git a/src/api/java/thaumcraft/api/visnet/VisNetHandler.java b/src/api/java/thaumcraft/api/visnet/VisNetHandler.java index cb9714c..9eac9c1 100644 --- a/src/api/java/thaumcraft/api/visnet/VisNetHandler.java +++ b/src/api/java/thaumcraft/api/visnet/VisNetHandler.java @@ -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>> sources = new HashMap>>(); @@ -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 cache = new ArrayList(); public static ArrayList findClosestNodes(TileVisNode target, - TileVisNode root, ArrayList in) { - TileVisNode closestChild = null; + TileVisNode parent, ArrayList in) { + + if (cache.size() > 512 || cache.contains(new WorldCoordinates(parent))) return in; + cache.add(new WorldCoordinates(parent)); + + for (WeakReference childWR : parent.getChildren()) { + TileVisNode child = childWR.get(); - for (WeakReference 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> // noderef = new HashMap>(); diff --git a/src/api/java/thaumcraft/api/wands/FocusUpgradeType.java b/src/api/java/thaumcraft/api/wands/FocusUpgradeType.java new file mode 100644 index 0000000..2c42b33 --- /dev/null +++ b/src/api/java/thaumcraft/api/wands/FocusUpgradeType.java @@ -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) { + 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)); + + +} diff --git a/src/api/java/thaumcraft/api/wands/IWandFocus.java b/src/api/java/thaumcraft/api/wands/IWandFocus.java deleted file mode 100644 index da4b9ae..0000000 --- a/src/api/java/thaumcraft/api/wands/IWandFocus.java +++ /dev/null @@ -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 - *
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); - - - - - -} diff --git a/src/api/java/thaumcraft/api/wands/ItemFocusBasic.java b/src/api/java/thaumcraft/api/wands/ItemFocusBasic.java index 3590052..37d6de6 100644 --- a/src/api/java/thaumcraft/api/wands/ItemFocusBasic.java +++ b/src/api/java/thaumcraft/api/wands/ItemFocusBasic.java @@ -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 map = new LinkedHashMap(); + 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 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); + } + } } diff --git a/src/main/java/fox/spiteful/forbidden/Config.java b/src/main/java/fox/spiteful/forbidden/Config.java index fea063d..594b414 100644 --- a/src/main/java/fox/spiteful/forbidden/Config.java +++ b/src/main/java/fox/spiteful/forbidden/Config.java @@ -48,6 +48,7 @@ public class Config { public static boolean am2 = false; public static boolean tt = true; public static boolean tc = true; + public static boolean special = true; public static int wrathCost = 5; public static int wrathEff = 4; @@ -91,6 +92,7 @@ public class Config { am2 = conf.get("compatibility", "Ars Magica 2 Interaction", am2, "AM2 interaction is unsupported. Enable at your own risk.").getBoolean(false); tt = conf.get("compatibility", "Thaumic Tinkerer Interaction", tt).getBoolean(true); tc = conf.get("compatibility", "Tinkers Construct Interaction", tc).getBoolean(true); + special = conf.get("compatibility", "Special Mobs Interaction", special).getBoolean(true); } catch (Exception e) { LogHandler.log(Level.ERROR, e, "Had a problem loading its configuration."); } finally { diff --git a/src/main/java/fox/spiteful/forbidden/WandOverlord.java b/src/main/java/fox/spiteful/forbidden/WandOverlord.java index e38f239..884a8c9 100644 --- a/src/main/java/fox/spiteful/forbidden/WandOverlord.java +++ b/src/main/java/fox/spiteful/forbidden/WandOverlord.java @@ -19,7 +19,7 @@ public class WandOverlord implements IWandTriggerManager { } public boolean hellfire(World world, ItemStack wand, EntityPlayer player, int x, int y, int z, int side) { - if (world.isRemote || wand == null || !(wand.getItem() instanceof ItemWandCasting) || ((ItemWandCasting) wand.getItem()).getFocus(wand) != null || !ResearchManager.isResearchComplete(player.getCommandSenderName(), "HELLFIRE") || !player.canPlayerEdit(x, y, z, side, new ItemStack(Items.fire_charge))) + if (world.isRemote || wand == null || !(wand.getItem() instanceof ItemWandCasting) || ((ItemWandCasting) wand.getItem()).getFocusItem(wand) != null || !ResearchManager.isResearchComplete(player.getCommandSenderName(), "HELLFIRE") || !player.canPlayerEdit(x, y, z, side, new ItemStack(Items.fire_charge))) return false; if (world.isAirBlock(x, y + 1, z) && ((ItemWandCasting) wand.getItem()).consumeVis(wand, player, Aspect.FIRE, 2, false)) { diff --git a/src/main/java/fox/spiteful/forbidden/blocks/BlockWrathCage.java b/src/main/java/fox/spiteful/forbidden/blocks/BlockWrathCage.java index b839a43..ec09861 100644 --- a/src/main/java/fox/spiteful/forbidden/blocks/BlockWrathCage.java +++ b/src/main/java/fox/spiteful/forbidden/blocks/BlockWrathCage.java @@ -50,6 +50,8 @@ public class BlockWrathCage extends BlockContainer { NBTTagCompound nbttagcompound = held.getTagCompound(); if (nbttagcompound == null) return false; + if(!nbttagcompound.hasKey("mob")) + return false; String string = nbttagcompound.getString("mob"); if (string != null) { if (!world.isRemote) { diff --git a/src/main/java/fox/spiteful/forbidden/compat/Compat.java b/src/main/java/fox/spiteful/forbidden/compat/Compat.java index 602cd34..52da71d 100644 --- a/src/main/java/fox/spiteful/forbidden/compat/Compat.java +++ b/src/main/java/fox/spiteful/forbidden/compat/Compat.java @@ -46,6 +46,7 @@ public class Compat { public static boolean am2 = false; public static boolean botan = false; public static boolean tc = false; + public static boolean special = false; public static void initiate() { if(!Config.crossMod) @@ -57,6 +58,7 @@ public class Compat { am2 = Config.am2 && Loader.isModLoaded("arsmagica2"); botan = Config.botan && Loader.isModLoaded("Botania"); tc = Config.tc && Loader.isModLoaded("TConstruct"); + special = Config.wrathCage && Config.special && Loader.isModLoaded("SpecialMobs"); } public static void compatify() { @@ -220,5 +222,102 @@ public class Compat { if (botan) { ForbiddenBotany.flowerPowerHippymancy(); } + + if(special){ + Config.spawnerMobs.put("SpecialMobs.SpecialCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.BabyCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.FlyingCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.MotherCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.ToughCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.WebCaveSpider", Aspect.POISON); + Config.spawnerMobs.put("SpecialMobs.WitchCaveSpider", Aspect.POISON); + + Config.spawnerMobs.put("SpecialMobs.SpecialCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.ArmorCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.DarkCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.DeathCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.DirtCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.DoomCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.DrowningCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.EnderCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.FireCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.JumpingCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.LightningCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.MiniCreeper", Aspect.FIRE); + Config.spawnerMobs.put("SpecialMobs.SplittingCreeper", Aspect.FIRE); + + Config.spawnerMobs.put("SpecialMobs.SpecialEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.BlindingEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.CursedEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.IcyEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.LightningEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.MiniEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.MirageEnderman", Aspect.ELDRITCH); + Config.spawnerMobs.put("SpecialMobs.ThiefEnderman", Aspect.ELDRITCH); + + Config.spawnerMobs.put("SpecialMobs.SpecialGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.BabyGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.FaintGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.FighterGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.KingGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.MiniGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.QueenGhast", DarkAspects.NETHER); + Config.spawnerMobs.put("SpecialMobs.UnholyGhast", DarkAspects.NETHER); + + Config.spawnerMobs.put("SpecialMobs.SpecialPigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.BrutishPigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.FishingPigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.GiantPigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.HungryPigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.PlaguePigZombie", Aspect.GREED); + Config.spawnerMobs.put("SpecialMobs.VampirePigZombie", Aspect.GREED); + + Aspect silver; + if(Config.silverfishEmeralds) + silver = Aspect.GREED; + else + silver = Aspect.BEAST; + + Config.spawnerMobs.put("SpecialMobs.SpecialSilverfish", silver); + Config.spawnerMobs.put("SpecialMobs.BlindingSilverfish", silver); + Config.spawnerMobs.put("SpecialMobs.FishingSilverfish", silver); + Config.spawnerMobs.put("SpecialMobs.FlyingSilverfish", silver); + Config.spawnerMobs.put("SpecialMobs.PoisonSilverfish", silver); + Config.spawnerMobs.put("SpecialMobs.ToughSilverfish", silver); + + Config.spawnerMobs.put("SpecialMobs.SpecialSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.BrutishSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.FireSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.GatlingSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.GiantSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.PoisonSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.SniperSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.SpitfireSkeleton", Aspect.DEATH); + Config.spawnerMobs.put("SpecialMobs.ThiefSkeleton", Aspect.DEATH); + + Config.spawnerMobs.put("SpecialMobs.SpecialSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.BabySpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.DesertSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.FlyingSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.GhostSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.GiantSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.HungrySpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.MotherSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.PaleSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.PoisonSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.SmallSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.ToughSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.WebSpider", Aspect.CLOTH); + Config.spawnerMobs.put("SpecialMobs.WitchSpider", Aspect.CLOTH); + + Config.spawnerMobs.put("SpecialMobs.SpecialZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.BrutishZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.FireZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.FishingZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.GiantZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.HungryZombie", Aspect.FLESH); + Config.spawnerMobs.put("SpecialMobs.PlagueZombie", Aspect.FLESH); + + } } } \ No newline at end of file diff --git a/src/main/java/fox/spiteful/forbidden/items/ItemDivineOrb.java b/src/main/java/fox/spiteful/forbidden/items/ItemDivineOrb.java index a40d91d..155c2b1 100644 --- a/src/main/java/fox/spiteful/forbidden/items/ItemDivineOrb.java +++ b/src/main/java/fox/spiteful/forbidden/items/ItemDivineOrb.java @@ -63,7 +63,8 @@ public class ItemDivineOrb extends Item implements IBloodOrb, IBindable, IWarpin return itemstack; } - player.setHealth(player.getHealth() - 1); + if(!player.capabilities.isCreativeMode) + player.setHealth(player.getHealth() - 1); SoulNetworkHandler.addCurrentEssenceToMaximum(itemTag.getString("ownerName"), 200, 700000000); return itemstack; diff --git a/src/main/java/fox/spiteful/forbidden/items/ItemMobCrystal.java b/src/main/java/fox/spiteful/forbidden/items/ItemMobCrystal.java index 15b1c58..aab9969 100644 --- a/src/main/java/fox/spiteful/forbidden/items/ItemMobCrystal.java +++ b/src/main/java/fox/spiteful/forbidden/items/ItemMobCrystal.java @@ -34,13 +34,15 @@ public class ItemMobCrystal extends Item { public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean z) { if (stack.hasTagCompound()) { NBTTagCompound nbttagcompound = stack.getTagCompound(); - String string = nbttagcompound.getString("mob"); + if(nbttagcompound.hasKey("mob")) { + String string = nbttagcompound.getString("mob"); - if (string != null) { - Aspect mobAspect = Config.spawnerMobs.get(string); - if (mobAspect != null) - list.add(mobAspect.getName()); - } + if (string != null) { + Aspect mobAspect = Config.spawnerMobs.get(string); + if (mobAspect != null) + list.add(mobAspect.getName()); + } + } } } @@ -72,9 +74,7 @@ public class ItemMobCrystal extends Item { public IIcon getIconIndex(ItemStack stack) { if (stack.hasTagCompound()) { NBTTagCompound nbttagcompound = stack.getTagCompound(); - String string = nbttagcompound.getString("mob"); - - if (string != null) + if (nbttagcompound.hasKey("mob")) return icons[1]; } @@ -98,10 +98,12 @@ public class ItemMobCrystal extends Item { public String getItemStackDisplayName(ItemStack stack) { if (stack.hasTagCompound()) { NBTTagCompound nbttagcompound = stack.getTagCompound(); - String string = nbttagcompound.getString("mob"); + if(nbttagcompound.hasKey("mob")) { + String string = nbttagcompound.getString("mob"); - if (string != null) - return ("" + StatCollector.translateToLocal("entity." + string + ".name") + " " + StatCollector.translateToLocal("item.MobCrystal.name")).trim(); + if (string != null) + return ("" + StatCollector.translateToLocal("entity." + string + ".name") + " " + StatCollector.translateToLocal("item.MobCrystal.name")).trim(); + } } return ("" + StatCollector.translateToLocal("item.MobCrystalEmpty.name")).trim(); diff --git a/src/main/java/fox/spiteful/forbidden/items/ItemSubCollar.java b/src/main/java/fox/spiteful/forbidden/items/ItemSubCollar.java index 711ea77..fe1b913 100644 --- a/src/main/java/fox/spiteful/forbidden/items/ItemSubCollar.java +++ b/src/main/java/fox/spiteful/forbidden/items/ItemSubCollar.java @@ -7,10 +7,12 @@ import fox.spiteful.forbidden.Forbidden; import fox.spiteful.forbidden.compat.Compat; import fox.spiteful.forbidden.potions.DarkPotions; import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; @@ -111,10 +113,19 @@ public class ItemSubCollar extends ItemAmuletVis { baubles.setInventorySlotContents(0, itemstack.copy()); itemstack.stackSize = 0; sub.addChatMessage(new ChatComponentText(player.getDisplayName() + " places a collar around your neck.")); + player.addChatMessage(new ChatComponentText("You place the collar around " + sub.getDisplayName() + "'s neck.")); return true; } + else + player.addChatMessage(new ChatComponentText(sub.getDisplayName() + " is already wearing something around their neck!")); } return false; } + @SideOnly(Side.CLIENT) + @Override + public void getSubItems(Item item, CreativeTabs xCreativeTabs, List list) { + list.add(new ItemStack(item, 1, 0)); + } + } diff --git a/src/main/resources/assets/forbidden/textures/models/wand_cap_elementium.png b/src/main/resources/assets/forbidden/textures/models/wand_cap_elementium.png new file mode 100644 index 0000000..8d7880c Binary files /dev/null and b/src/main/resources/assets/forbidden/textures/models/wand_cap_elementium.png differ