package thaumcraft.api; 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; import net.minecraftforge.oredict.OreDictionary; import thaumcraft.api.aspects.Aspect; import thaumcraft.api.aspects.AspectList; import thaumcraft.api.aspects.IEssentiaTransport; public class ThaumcraftApiHelper { public static AspectList cullTags(AspectList temp) { AspectList temp2 = new AspectList(); for (Aspect tag:temp.getAspects()) { if (tag!=null) temp2.add(tag, temp.getAmount(tag)); } while (temp2!=null && temp2.size()>6) { Aspect lowest = null; float low = Short.MAX_VALUE; for (Aspect tag:temp2.getAspects()) { if (tag==null) continue; 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 allAspects= new HashMap(); private static HashMap allCompoundAspects= new HashMap(); public static AspectList getAllAspects(int amount) { if (allAspects.get(amount)==null) { AspectList al = new AspectList(); for (Aspect aspect:Aspect.aspects.values()) { al.add(aspect, amount); } allAspects.put(amount, al); } return allAspects.get(amount); } public static AspectList getAllCompoundAspects(int amount) { if (allCompoundAspects.get(amount)==null) { AspectList al = new AspectList(); for (Aspect aspect:Aspect.getCompoundAspects()) { al.add(aspect, amount); } allCompoundAspects.put(amount, al); } return allCompoundAspects.get(amount); } /** * 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 * @param wand the wand itemstack * @param player the player using the wand * @param cost the cost of the operation. * @param doit actually subtract the vis from the wand if true - if false just simulate the result * @param crafting is this a crafting operation or not - if * false then things like frugal and potency will apply to the costs * @return was the vis successfully subtracted */ public static boolean consumeVisFromWand(ItemStack wand, EntityPlayer player, AspectList cost, boolean doit, boolean crafting) { return ThaumcraftApi.internalMethods.consumeVisFromWand(wand, player, cost, doit, crafting); } /** * Subtract vis for use by a crafting mechanic. Costs are calculated slightly * differently and things like the frugal enchant is ignored * Must NOT be multiplied by 100 - send the actual vis cost * @param wand the wand itemstack * @param player the player using the wand * @param cost the cost of the operation. * @param doit actually subtract the vis from the wand if true - if false just simulate the result * @return was the vis successfully subtracted */ public static boolean consumeVisFromWandCrafting(ItemStack wand, EntityPlayer player, AspectList cost, boolean doit) { return ThaumcraftApi.internalMethods.consumeVisFromWandCrafting(wand, player, cost, doit); } /** * 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 * frugal don't effect them * @param player the player using the wand * @param cost the cost of the operation. * @return was the vis successfully subtracted */ public static boolean consumeVisFromInventory(EntityPlayer player, AspectList cost) { return ThaumcraftApi.internalMethods.consumeVisFromInventory(player, cost); } /** * This adds permanents or temporary warp to a player. It will automatically be synced clientside * @param player the player using the wand * @param amount how much warp to add. Negative amounts are only valid for temporary warp * @param temporary add temporary warp instead of permanent */ public static void addWarpToPlayer(EntityPlayer player, int amount, boolean temporary) { ThaumcraftApi.internalMethods.addWarpToPlayer(player, amount, temporary); } /** * This "sticky" warp to a player. Sticky warp is permanent warp that can be removed. * It will automatically be synced clientside * @param player the player using the wand * @param amount how much warp to add. Can have negative amounts. */ public static void addStickyWarpToPlayer(EntityPlayer player, int amount) { 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; } else { return null; } } else { return null; } } }