├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src ├── api │ └── java │ │ └── thaumcraft │ │ └── api │ │ ├── entities │ │ └── ITaintedMob.java │ │ ├── nodes │ │ ├── NodeModifier.java │ │ ├── NodeType.java │ │ ├── IRevealer.java │ │ └── INode.java │ │ ├── package-info.java │ │ ├── IScribeTools.java │ │ ├── IRepairable.java │ │ ├── research │ │ ├── IScanEventHandler.java │ │ ├── ResearchCategoryList.java │ │ ├── ScanResult.java │ │ ├── ResearchCategories.java │ │ ├── ResearchPage.java │ │ └── ResearchItem.java │ │ ├── aspects │ │ ├── IAspectSource.java │ │ ├── IEssentiaContainerItem.java │ │ ├── IAspectContainer.java │ │ ├── IEssentiaTransport.java │ │ ├── AspectSourceHelper.java │ │ ├── AspectList.java │ │ └── Aspect.java │ │ ├── ItemRunic.java │ │ ├── wands │ │ ├── IWandRodOnUpdate.java │ │ ├── IWandTriggerManager.java │ │ ├── IWandable.java │ │ ├── StaffRod.java │ │ ├── IWandFocus.java │ │ ├── WandCap.java │ │ ├── WandRod.java │ │ ├── ItemFocusBasic.java │ │ └── WandTriggerRegistry.java │ │ ├── crafting │ │ ├── IInfusionStabiliser.java │ │ ├── IArcaneRecipe.java │ │ ├── CrucibleRecipe.java │ │ ├── InfusionRecipe.java │ │ ├── ShapelessArcaneRecipe.java │ │ ├── InfusionEnchantmentRecipe.java │ │ └── ShapedArcaneRecipe.java │ │ ├── IRepairableExtended.java │ │ ├── IRunicArmor.java │ │ ├── IGoggles.java │ │ ├── IVisDiscountGear.java │ │ ├── damagesource │ │ ├── DamageSourceIndirectThaumcraftEntity.java │ │ └── DamageSourceThaumcraft.java │ │ ├── potions │ │ ├── PotionVisExhaust.java │ │ └── PotionFluxTaint.java │ │ ├── TileThaumcraft.java │ │ ├── ItemApi.java │ │ ├── WorldCoordinates.java │ │ ├── visnet │ │ ├── TileVisNode.java │ │ └── VisNetHandler.java │ │ ├── ThaumcraftApiHelper.java │ │ └── ThaumcraftApi.java └── main │ ├── resources │ ├── assets │ │ └── nodalmechanics │ │ │ ├── textures │ │ │ └── items │ │ │ │ └── itemMatrix.png │ │ │ └── lang │ │ │ ├── zh_CN.lang │ │ │ ├── ru_RU.lang │ │ │ ├── en_US.lang │ │ │ └── fr_FR.lang │ └── mcmod.info │ └── java │ └── shukaro │ └── nodalmechanics │ ├── net │ ├── CommonProxy.java │ └── ClientProxy.java │ ├── items │ ├── NodalItems.java │ └── ItemMatrix.java │ ├── gui │ └── NodalTab.java │ ├── util │ └── FormatCodes.java │ ├── research │ └── NodalResearch.java │ ├── NodalMechanics.java │ └── recipe │ ├── RecipeNode.java │ ├── RecipeAttune.java │ └── NodalRecipes.java ├── .gitignore ├── .gitattributes ├── README.md ├── gradlew.bat └── gradlew /gradle.properties: -------------------------------------------------------------------------------- 1 | build_number=DEV 2 | forge_version=1.7.10-10.13.0.1180 3 | mod_version=1.0 4 | mc_version=1.7 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AKA-Syenite/Nodal-Mechanics/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/entities/ITaintedMob.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.entities; 2 | 3 | public interface ITaintedMob { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/nodes/NodeModifier.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.nodes; 2 | 3 | public enum NodeModifier 4 | { 5 | BRIGHT, PALE, FADING 6 | } -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/nodes/NodeType.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.nodes; 2 | 3 | public enum NodeType 4 | { 5 | NORMAL, UNSTABLE, DARK, TAINTED, HUNGRY, PURE 6 | } -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/package-info.java: -------------------------------------------------------------------------------- 1 | @API(owner = "Thaumcraft", apiVersion = "4.2.0.0", provides = "Thaumcraft|API") 2 | package thaumcraft.api; 3 | 4 | import cpw.mods.fml.common.API; 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/nodalmechanics/textures/items/itemMatrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AKA-Syenite/Nodal-Mechanics/HEAD/src/main/resources/assets/nodalmechanics/textures/items/itemMatrix.png -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/net/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.net; 2 | 3 | public class CommonProxy 4 | { 5 | public void init() 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/net/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.net; 2 | 3 | public class ClientProxy extends CommonProxy 4 | { 5 | public void init() 6 | { 7 | super.init(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IScribeTools.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | 4 | /** 5 | * 6 | * @author Azanor 7 | * 8 | * Interface used to identify scribing tool items used in research table 9 | * 10 | */ 11 | 12 | public interface IScribeTools { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jul 02 15:54:47 CDT 2014 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle cache files & directories 2 | bin/ 3 | build/ 4 | libs/ 5 | eclipse/ 6 | minecraft/ 7 | .classpath 8 | .gradle/ 9 | .project 10 | .settings/ 11 | 12 | # Ignore OS cache files & directories 13 | *.DS_Store 14 | _MACOSX 15 | Thumbs.db 16 | 17 | # Ignore IntelliJ files 18 | out/ 19 | *.ipr 20 | *.iml 21 | *.iws 22 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IRepairable.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | 4 | 5 | /** 6 | * @author Azanor 7 | * Items, armor and tools with this interface can receive the Repair enchantment. 8 | * Repairs 1 point of durability every 10 seconds (2 for repair II) 9 | */ 10 | public interface IRepairable { 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/research/IScanEventHandler.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.research; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.world.World; 6 | 7 | public interface IScanEventHandler { 8 | ScanResult scanPhenomena(ItemStack stack, World world, EntityPlayer player); 9 | } 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted to native line endings on checkout. 5 | *.md text 6 | *.info text 7 | *.txt text 8 | 9 | # Denote all files that are truly binary and should not be modified. 10 | *.png binary 11 | *.jpg binary 12 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/IAspectSource.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | 4 | 5 | /** 6 | * @author Azanor 7 | * 8 | * This interface is implemented by tile entites (or possibly anything else) like jars 9 | * so that they can act as an essentia source for blocks like the infusion altar. 10 | * 11 | */ 12 | public interface IAspectSource extends IAspectContainer { 13 | 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/items/NodalItems.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.items; 2 | 3 | import cpw.mods.fml.common.registry.GameRegistry; 4 | 5 | public class NodalItems 6 | { 7 | public static ItemMatrix itemMatrix; 8 | 9 | public static void initItems() 10 | { 11 | itemMatrix = new ItemMatrix(); 12 | GameRegistry.registerItem(itemMatrix, itemMatrix.getUnlocalizedName()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/ItemRunic.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.item.Item; 4 | import net.minecraft.item.ItemStack; 5 | 6 | public class ItemRunic extends Item implements IRunicArmor { 7 | 8 | int charge; 9 | 10 | public ItemRunic (int charge) 11 | { 12 | super(); 13 | this.charge = charge; 14 | } 15 | 16 | @Override 17 | public int getRunicCharge(ItemStack itemstack) { 18 | return charge; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/IWandRodOnUpdate.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | 6 | /** 7 | * 8 | * @author azanor 9 | * 10 | * Implemented by a class that you wish to be called whenever a wand with this rod performs its 11 | * update tick. 12 | * 13 | */ 14 | public interface IWandRodOnUpdate { 15 | void onUpdate(ItemStack itemstack, EntityPlayer player); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "NodalMechanics", 4 | "name": "NodalMechanics", 5 | "description": "", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authors": [ 11 | "Shukaro" 12 | ], 13 | "credits": "All the contributors", 14 | "logoFile": "", 15 | "screenshots": [ 16 | ], 17 | "parent": "", 18 | "dependencies": [ 19 | "MinecraftForge","Thaumcraft" 20 | ] 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/gui/NodalTab.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.gui; 2 | 3 | import net.minecraft.creativetab.CreativeTabs; 4 | import net.minecraft.item.Item; 5 | import shukaro.nodalmechanics.items.NodalItems; 6 | 7 | public class NodalTab extends CreativeTabs 8 | { 9 | public NodalTab(String label) 10 | { 11 | super(label); 12 | } 13 | 14 | @Override 15 | public Item getTabIconItem() 16 | { 17 | return NodalItems.itemMatrix; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/IInfusionStabiliser.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import net.minecraft.world.World; 4 | 5 | /** 6 | * 7 | * @author Azanor 8 | * 9 | * Blocks that implement this interface act as infusion crafting stabilisers like candles and skulls 10 | * 11 | */ 12 | public interface IInfusionStabiliser { 13 | 14 | /** 15 | * returns true if the block can stabilise things 16 | */ 17 | public boolean canStabaliseInfusion(World world, int x, int y, int z); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/assets/nodalmechanics/lang/zh_CN.lang: -------------------------------------------------------------------------------- 1 | itemGroup.nodalmechanics.tab=节点学 2 | 3 | item.nodalmechanics.matrix.attuned.name=节点基体(已调制) 4 | item.nodalmechanics.matrix.unattuned.name=节点基体(未调制) 5 | tooltip.nodalmechanics.matrix.attuned=微弱的响声... 6 | tooltip.nodalmechanics.matrix.unattuned=空 7 | 8 | tc.research_name.NODECATALYZATION=节点催生 9 | tc.research_text.NODECATALYZATION=无中...生有 10 | 11 | nodalmechanics.nodecatalyzation.research=将你关于节点和要素罐子的学识付之一用,你成功的发明出了一种催生出新节点的方法.
组合一些要素源质来调制节点基体就能获得一个节点的种子,之后给其注入大量的要素就能激发它的生成. 12 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IRepairableExtended.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | 6 | 7 | 8 | /** 9 | * @author Azanor 10 | * Items, armor and tools with this interface can receive the Repair enchantment. 11 | * Repairs 1 point of durability every 10 seconds (2 for repair II) 12 | */ 13 | public interface IRepairableExtended extends IRepairable { 14 | 15 | public boolean doRepair(ItemStack stack, EntityPlayer player, int enchantlevel); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/nodes/IRevealer.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.nodes; 2 | 3 | import net.minecraft.entity.EntityLivingBase; 4 | import net.minecraft.item.ItemStack; 5 | 6 | /** 7 | * 8 | * @author Azanor 9 | * 10 | * Equipped head slot items that extend this class will make nodes visible in world. 11 | * 12 | */ 13 | 14 | public interface IRevealer { 15 | 16 | /* 17 | * If this method returns true the nodes will be visible. 18 | */ 19 | public boolean showNodes(ItemStack itemstack, EntityLivingBase player); 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/IWandTriggerManager.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.world.World; 6 | 7 | public interface IWandTriggerManager { 8 | 9 | /** 10 | * This class will be called by wands with the proper parameters. It is up to you to decide what to do with them. 11 | */ 12 | public boolean performTrigger(World world, ItemStack wand, EntityPlayer player, 13 | int x, int y, int z, int side, int event); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IRunicArmor.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | /** 6 | * 7 | * @author Azanor 8 | * 9 | * Armor or bauble slot items that implement this interface can provide runic shielding. 10 | * Recharging, hardening, etc. is handled internally by thaumcraft. 11 | * 12 | */ 13 | 14 | public interface IRunicArmor { 15 | 16 | /** 17 | * returns how much charge this item can provide. This is the base shielding value - any hardening is stored and calculated internally. 18 | */ 19 | public int getRunicCharge(ItemStack itemstack); 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IGoggles.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.entity.EntityLivingBase; 4 | import net.minecraft.item.ItemStack; 5 | 6 | /** 7 | * 8 | * @author Azanor 9 | * 10 | * Equipped head slot items that extend this class will be able to perform most functions that 11 | * goggles of revealing can apart from view nodes which is handled by IRevealer. 12 | * 13 | */ 14 | 15 | public interface IGoggles { 16 | 17 | /* 18 | * If this method returns true things like block essentia contents will be shown. 19 | */ 20 | public boolean showIngamePopups(ItemStack itemstack, EntityLivingBase player); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/IVisDiscountGear.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import thaumcraft.api.aspects.Aspect; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.item.ItemStack; 6 | 7 | 8 | /** 9 | * @author Azanor 10 | * ItemArmor with this interface will grant a discount to the vis cost of actions the wearer performs with casting wands. 11 | * The amount returned is the percentage by which the cost is discounted. There is a built-int max discount of 50%, but 12 | * individual items really shouldn't have a discount more than 5% 13 | */ 14 | public interface IVisDiscountGear { 15 | 16 | int getVisDiscount(ItemStack stack, EntityPlayer player, Aspect aspect); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/IWandable.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.world.World; 6 | 7 | /** 8 | * 9 | * @author azanor 10 | * 11 | * Add this to a tile entity that you wish wands to interact with in some way. 12 | * 13 | */ 14 | 15 | public interface IWandable { 16 | 17 | public int onWandRightClick(World world, ItemStack wandstack, EntityPlayer player, int x, int y, int z, int side, int md); 18 | 19 | public ItemStack onWandRightClick(World world, ItemStack wandstack, EntityPlayer player); 20 | 21 | public void onUsingWandTick(ItemStack wandstack, EntityPlayer player, int count); 22 | 23 | public void onWandStoppedUsing(ItemStack wandstack, World world, EntityPlayer player, int count); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/assets/nodalmechanics/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | itemGroup.nodalmechanics.tab=Nodal Mechanics 2 | 3 | item.nodalmechanics.matrix.attuned.name=Настроенная матрица узла 4 | item.nodalmechanics.matrix.unattuned.name=Ненастроенная матрица узла 5 | tooltip.nodalmechanics.matrix.attuned=Слабое гудение... 6 | tooltip.nodalmechanics.matrix.unattuned=Пусто 7 | 8 | tc.research_name.NODECATALYZATION=Катализация узла ауры 9 | tc.research_text.NODECATALYZATION=Что-то из ничего 10 | 11 | nodalmechanics.nodecatalyzation.research=Соединив Ваши знания об узлах ауры и заключении их в банки, Вы успешно открыли способ создания новых узлов ауры.
Настраивая свежесозданную пустую матрицу узла ауры с помощью любых комбинаций эссенций, Вы создаёте источник узла ауры, а затем, применив большой объём подходящей энергии Вис, наполняете источник искрой жизни для роста. 12 | -------------------------------------------------------------------------------- /src/main/resources/assets/nodalmechanics/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | itemGroup.nodalmechanics.tab=Nodal Mechanics 2 | 3 | item.nodalmechanics.matrix.attuned.name=Attuned Node Matrix 4 | item.nodalmechanics.matrix.unattuned.name=Unattuned Node Matrix 5 | tooltip.nodalmechanics.matrix.attuned=Faintly humming... 6 | tooltip.nodalmechanics.matrix.unattuned=Empty 7 | 8 | tc.research_name.NODECATALYZATION=Node Catalyzation 9 | tc.research_text.NODECATALYZATION=From nothing... Something 10 | 11 | nodalmechanics.nodecatalyzation.research=By applying your knowledge of nodes and warded jars, you have successfully devised a method of catalyzing the formation of new nodes.
By attuning a freshly-crafted blank node matrix towards any combination of essentia to provide the seed for a node's growth, you can then infuse it with a large amount of compatible vis to spark the node's growth. -------------------------------------------------------------------------------- /src/main/resources/assets/nodalmechanics/lang/fr_FR.lang: -------------------------------------------------------------------------------- 1 | itemGroup.nodalmechanics.tab=Mécaniques des Noeuds 2 | 3 | item.nodalmechanics.matrix.attuned.name=Matrice de Noeud Lié 4 | item.nodalmechanics.matrix.unattuned.name=Matrice de Noeud Non Lié 5 | tooltip.nodalmechanics.matrix.attuned=Bourdonnement légèrement... 6 | tooltip.nodalmechanics.matrix.unattuned=Vide 7 | 8 | tc.research_name.NODECATALYZATION=Catalyse des Noeuds 9 | tc.research_text.NODECATALYZATION=De rien.... Quelque chose 10 | 11 | nodalmechanics.nodecatalyzation.research=Par application de votre connaissance des noeuds et jarres, vous avez trouvé une façon incroyable a former les nouvelles noeuds.
Par lier une nouvelle matrice de noeud au n'importe quel combination d'essentia pour créer une graine pour la croissance d'une noeud. Là , vous pouvez infuser la graine avec beaucoup de vis pour créer une nouvelle noeud. 12 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/damagesource/DamageSourceIndirectThaumcraftEntity.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.damagesource; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.DamageSource; 5 | import net.minecraft.util.EntityDamageSourceIndirect; 6 | 7 | public class DamageSourceIndirectThaumcraftEntity extends EntityDamageSourceIndirect { 8 | 9 | private boolean fireDamage; 10 | private float hungerDamage; 11 | private boolean isUnblockable; 12 | 13 | 14 | public DamageSourceIndirectThaumcraftEntity(String par1Str, 15 | Entity par2Entity, Entity par3Entity) { 16 | super(par1Str, par2Entity, par3Entity); 17 | } 18 | 19 | 20 | public DamageSource setFireDamage() 21 | { 22 | this.fireDamage = true; 23 | return this; 24 | } 25 | 26 | public DamageSource setDamageBypassesArmor() 27 | { 28 | this.isUnblockable = true; 29 | this.hungerDamage = 0.0F; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/util/FormatCodes.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.util; 2 | 3 | /** 4 | * Enum of code codes used by the vanilla Minecraft font renderer 5 | * 6 | * @author MachineMuse 7 | */ 8 | public enum FormatCodes 9 | { 10 | Black("\u00A70"), 11 | DarkBlue("\u00A71"), 12 | DarkGreen("\u00A72"), 13 | DarkAqua("\u00A73"), 14 | DarkRed("\u00A74"), 15 | Purple("\u00A75"), 16 | Gold("\u00A76"), 17 | Grey("\u00A77"), 18 | DarkGrey("\u00A78"), 19 | Indigo("\u00A79"), 20 | BrightGreen("\u00A7a"), 21 | Aqua("\u00A7b"), 22 | Red("\u00A7c"), 23 | Pink("\u00A7d"), 24 | Yellow("\u00A7e"), 25 | White("\u00A7f"), 26 | RandomChar("\u00A7k"), 27 | Bold("\u00A7l"), 28 | Strike("\u00A7m"), 29 | Underlined("\u00A7n"), 30 | Italic("\u00A7o"), 31 | Reset("\u00A7r"); 32 | 33 | public String code; 34 | 35 | private FormatCodes(String s) 36 | { 37 | this.code = s; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/IArcaneRecipe.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import thaumcraft.api.aspects.AspectList; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.inventory.IInventory; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.world.World; 8 | 9 | public interface IArcaneRecipe 10 | { 11 | 12 | 13 | /** 14 | * Used to check if a recipe matches current crafting inventory 15 | * @param player 16 | */ 17 | boolean matches(IInventory var1, World world, EntityPlayer player); 18 | 19 | /** 20 | * Returns an Item that is the result of this recipe 21 | */ 22 | ItemStack getCraftingResult(IInventory var1); 23 | 24 | /** 25 | * Returns the size of the recipe area 26 | */ 27 | int getRecipeSize(); 28 | 29 | ItemStack getRecipeOutput(); 30 | AspectList getAspects(); 31 | AspectList getAspects(IInventory var1); 32 | String getResearch(); 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/research/ResearchCategoryList.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.research; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | public class ResearchCategoryList { 9 | 10 | /** Is the smallest column used on the GUI. */ 11 | public int minDisplayColumn; 12 | 13 | /** Is the smallest row used on the GUI. */ 14 | public int minDisplayRow; 15 | 16 | /** Is the biggest column used on the GUI. */ 17 | public int maxDisplayColumn; 18 | 19 | /** Is the biggest row used on the GUI. */ 20 | public int maxDisplayRow; 21 | 22 | /** display variables **/ 23 | public ResourceLocation icon; 24 | public ResourceLocation background; 25 | 26 | public ResearchCategoryList(ResourceLocation icon, ResourceLocation background) { 27 | this.icon = icon; 28 | this.background = background; 29 | } 30 | 31 | //Research 32 | public Map research = new HashMap(); 33 | 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nodal Mechanics 2 | 3 | Nodal Mechanics is an addon for [Thaumcraft 4](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1292130-thaumcraft-) by Azanor which adds the ability to craft aura nodes via infusion. 4 | 5 | ### Contributing 6 | Feel free to submit pull requests or issues to the tracker. To set up your environment, run `git clone https://github.com/Shukaro/Nodal-Mechanics.git`, then `gradlew setupDecompWorkspace`, and then either `gradlew eclipse` or `gradlew idea`. After that you can produce builds by running `gradlew build`. Ensure that `src/api` is available as a sources folder. 7 | 8 | ### Builds 9 | Builds are available via [Jenkins](http://76.72.175.100:8080/job/Nodal%20Mechanics/), stable builds are marked with a star. 10 | 11 | ### License 12 | You are free to do whatever you wish with this mod and this source code, provided that you provide proper attribution. 13 | Please don't distribute this mod behind any sort of ad-wall such as adf.ly or the like. 14 | Please make any modifications of this code open-source. 15 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/research/ScanResult.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.research; 2 | 3 | import net.minecraft.entity.Entity; 4 | 5 | public class ScanResult { 6 | public byte type = 0; //1=blocks,2=entities,3=phenomena 7 | public int id; 8 | public int meta; 9 | public Entity entity; 10 | public String phenomena; 11 | 12 | public ScanResult(byte type, int blockId, int blockMeta, Entity entity, 13 | String phenomena) { 14 | super(); 15 | this.type = type; 16 | this.id = blockId; 17 | this.meta = blockMeta; 18 | this.entity = entity; 19 | this.phenomena = phenomena; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object obj) { 24 | if (obj instanceof ScanResult) { 25 | ScanResult sr = (ScanResult) obj; 26 | if (type != sr.type) 27 | return false; 28 | if (type == 1 29 | && (id != sr.id || meta != sr.meta)) 30 | return false; 31 | if (type == 2 && entity.getEntityId() != sr.entity.getEntityId()) 32 | return false; 33 | if (type == 3 && !phenomena.equals(sr.phenomena)) 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/IEssentiaContainerItem.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | /** 6 | * 7 | * @author azanor 8 | * 9 | * Used by wispy essences and essentia phials to hold their aspects. 10 | * Useful for similar item containers that store their aspect information in nbt form so TC 11 | * automatically picks up the aspects they contain 12 | * 13 | */ 14 | public interface IEssentiaContainerItem { 15 | public AspectList getAspects(ItemStack itemstack); 16 | public void setAspects(ItemStack itemstack, AspectList aspects); 17 | } 18 | 19 | //Example implementation 20 | /* 21 | @Override 22 | public AspectList getAspects(ItemStack itemstack) { 23 | if (itemstack.hasTagCompound()) { 24 | AspectList aspects = new AspectList(); 25 | aspects.readFromNBT(itemstack.getTagCompound()); 26 | return aspects.size()>0?aspects:null; 27 | } 28 | return null; 29 | } 30 | 31 | @Override 32 | public void setAspects(ItemStack itemstack, AspectList aspects) { 33 | if (!itemstack.hasTagCompound()) itemstack.setTagCompound(new NBTTagCompound()); 34 | aspects.writeToNBT(itemstack.getTagCompound()); 35 | } 36 | */ -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/nodes/INode.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.nodes; 2 | 3 | import thaumcraft.api.aspects.AspectList; 4 | import thaumcraft.api.aspects.Aspect; 5 | import thaumcraft.api.aspects.IAspectContainer; 6 | 7 | public interface INode extends IAspectContainer { 8 | 9 | /** 10 | * Unique identifier to distinguish nodes. Normal node id's are based on world id and coordinates 11 | * @return 12 | */ 13 | public String getId(); 14 | 15 | public AspectList getAspectsBase(); 16 | 17 | /** 18 | * Return the type of node 19 | * @return 20 | */ 21 | public NodeType getNodeType(); 22 | 23 | /** 24 | * Set the type of node 25 | * @return 26 | */ 27 | public void setNodeType(NodeType nodeType); 28 | 29 | /** 30 | * Return the node modifier 31 | * @return 32 | */ 33 | public void setNodeModifier(NodeModifier nodeModifier); 34 | 35 | /** 36 | * Set the node modifier 37 | * @return 38 | */ 39 | public NodeModifier getNodeModifier(); 40 | 41 | /** 42 | * Return the maximum capacity of each aspect the node can hold 43 | * @return 44 | */ 45 | public int getNodeVisBase(Aspect aspect); 46 | 47 | /** 48 | * Set the maximum capacity of each aspect the node can hold 49 | * @return 50 | */ 51 | public void setNodeVisBase(Aspect aspect, short nodeVisBase); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/potions/PotionVisExhaust.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.potions; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.entity.EntityLivingBase; 5 | import net.minecraft.potion.Potion; 6 | import net.minecraft.util.ResourceLocation; 7 | import cpw.mods.fml.relauncher.Side; 8 | import cpw.mods.fml.relauncher.SideOnly; 9 | 10 | public class PotionVisExhaust extends Potion 11 | { 12 | public static PotionVisExhaust instance = null; // will be instantiated at runtime 13 | private int statusIconIndex = -1; 14 | 15 | public PotionVisExhaust(int par1, boolean par2, int par3) 16 | { 17 | super(par1,par2,par3); 18 | setIconIndex(0, 0); 19 | } 20 | 21 | public static void init() 22 | { 23 | instance.setPotionName("potion.visexhaust"); 24 | instance.setIconIndex(5, 1); 25 | instance.setEffectiveness(0.25D); 26 | } 27 | 28 | @Override 29 | public boolean isBadEffect() { 30 | return true; 31 | } 32 | 33 | @Override 34 | @SideOnly(Side.CLIENT) 35 | public int getStatusIconIndex() { 36 | Minecraft.getMinecraft().renderEngine.bindTexture(rl); 37 | return super.getStatusIconIndex(); 38 | } 39 | 40 | static final ResourceLocation rl = new ResourceLocation("thaumcraft","textures/misc/potions.png"); 41 | 42 | @Override 43 | public void performEffect(EntityLivingBase target, int par2) { 44 | 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/StaffRod.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | /** 7 | * 8 | * @author Azanor 9 | * 10 | * This class is used to keep the material information for the various rods. 11 | * It is also used to generate the wand recipes ingame. 12 | * 13 | */ 14 | public class StaffRod extends WandRod { 15 | 16 | boolean runes=false; 17 | 18 | public StaffRod(String tag, int capacity, ItemStack item, int craftCost) { 19 | super(tag+"_staff", capacity, item, craftCost); 20 | this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+tag+".png"); 21 | } 22 | 23 | public StaffRod(String tag, int capacity, ItemStack item, int craftCost, 24 | IWandRodOnUpdate onUpdate, ResourceLocation texture) { 25 | super(tag+"_staff", capacity, item, craftCost, onUpdate, texture); 26 | } 27 | 28 | public StaffRod(String tag, int capacity, ItemStack item, int craftCost, 29 | IWandRodOnUpdate onUpdate) { 30 | super(tag+"_staff", capacity, item, craftCost, onUpdate); 31 | this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+tag+".png"); 32 | } 33 | 34 | public StaffRod(String tag, int capacity, ItemStack item, int craftCost, 35 | ResourceLocation texture) { 36 | super(tag+"_staff", capacity, item, craftCost, texture); 37 | } 38 | 39 | public boolean hasRunes() { 40 | return runes; 41 | } 42 | 43 | public void setRunes(boolean hasRunes) { 44 | this.runes = hasRunes; 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/TileThaumcraft.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | import net.minecraft.network.NetworkManager; 5 | import net.minecraft.network.Packet; 6 | import net.minecraft.network.play.server.S35PacketUpdateTileEntity; 7 | import net.minecraft.tileentity.TileEntity; 8 | 9 | /** 10 | * 11 | * @author azanor 12 | * 13 | * Custom tile entity class I use for most of my tile entities. Setup in such a way that only 14 | * the nbt data within readCustomNBT / writeCustomNBT will be sent to the client when the tile 15 | * updates. Apart from all the normal TE data that gets sent that is. 16 | * 17 | */ 18 | public class TileThaumcraft extends TileEntity { 19 | 20 | //NBT stuff 21 | 22 | @Override 23 | public void readFromNBT(NBTTagCompound nbttagcompound) 24 | { 25 | super.readFromNBT(nbttagcompound); 26 | readCustomNBT(nbttagcompound); 27 | } 28 | 29 | public void readCustomNBT(NBTTagCompound nbttagcompound) 30 | { 31 | //TODO 32 | } 33 | 34 | @Override 35 | public void writeToNBT(NBTTagCompound nbttagcompound) 36 | { 37 | super.writeToNBT(nbttagcompound); 38 | writeCustomNBT(nbttagcompound); 39 | } 40 | 41 | public void writeCustomNBT(NBTTagCompound nbttagcompound) 42 | { 43 | //TODO 44 | } 45 | 46 | //Client Packet stuff 47 | @Override 48 | public Packet getDescriptionPacket() { 49 | NBTTagCompound nbttagcompound = new NBTTagCompound(); 50 | this.writeCustomNBT(nbttagcompound); 51 | return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, -999, nbttagcompound); 52 | } 53 | 54 | @Override 55 | public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { 56 | super.onDataPacket(net, pkt); 57 | this.readCustomNBT(pkt.func_148857_g()); 58 | } 59 | 60 | 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/damagesource/DamageSourceThaumcraft.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.damagesource; 2 | 3 | import net.minecraft.entity.EntityLivingBase; 4 | import net.minecraft.util.DamageSource; 5 | import net.minecraft.util.EntityDamageSource; 6 | 7 | public class DamageSourceThaumcraft extends DamageSource 8 | { 9 | 10 | public static DamageSource taint = new DamageSourceThaumcraft("taint").setDamageBypassesArmor().setMagicDamage(); 11 | public static DamageSource tentacle = new DamageSourceThaumcraft("tentacle"); 12 | public static DamageSource swarm = new DamageSourceThaumcraft("swarm"); 13 | public static DamageSource dissolve = new DamageSourceThaumcraft("dissolve").setDamageBypassesArmor(); 14 | 15 | protected DamageSourceThaumcraft(String par1Str) { 16 | super(par1Str); 17 | } 18 | 19 | /** This kind of damage can be blocked or not. */ 20 | private boolean isUnblockable = false; 21 | private boolean isDamageAllowedInCreativeMode = false; 22 | private float hungerDamage = 0.3F; 23 | 24 | /** This kind of damage is based on fire or not. */ 25 | private boolean fireDamage; 26 | 27 | /** This kind of damage is based on a projectile or not. */ 28 | private boolean projectile; 29 | 30 | /** 31 | * Whether this damage source will have its damage amount scaled based on the current difficulty. 32 | */ 33 | private boolean difficultyScaled; 34 | private boolean magicDamage = false; 35 | private boolean explosion = false; 36 | 37 | public static DamageSource causeSwarmDamage(EntityLivingBase par0EntityLiving) 38 | { 39 | return new EntityDamageSource("swarm", par0EntityLiving); 40 | } 41 | 42 | public static DamageSource causeTentacleDamage(EntityLivingBase par0EntityLiving) 43 | { 44 | return new EntityDamageSource("tentacle", par0EntityLiving); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/research/NodalResearch.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.research; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.util.StatCollector; 5 | import shukaro.nodalmechanics.items.NodalItems; 6 | import shukaro.nodalmechanics.recipe.NodalRecipes; 7 | import thaumcraft.api.ThaumcraftApi; 8 | import thaumcraft.api.aspects.Aspect; 9 | import thaumcraft.api.aspects.AspectList; 10 | import thaumcraft.api.research.ResearchItem; 11 | import thaumcraft.api.research.ResearchPage; 12 | 13 | public class NodalResearch 14 | { 15 | public static ResearchItem researchNodeCatalyzation; 16 | 17 | public static void initResearch() 18 | { 19 | researchNodeCatalyzation = new ResearchItem("NODECATALYZATION", "BASICS", new AspectList().add(Aspect.AURA, 6).add(Aspect.VOID, 3), -5, 4, 3, new ItemStack(NodalItems.itemMatrix)) 20 | .setPages(new ResearchPage[]{ 21 | new ResearchPage(StatCollector.translateToLocal("nodalmechanics.nodecatalyzation.research")), 22 | new ResearchPage(NodalRecipes.matrixRecipe), 23 | new ResearchPage(NodalRecipes.variedAttuneRecipe), 24 | new ResearchPage(NodalRecipes.sameAttuneRecipe), 25 | new ResearchPage(NodalRecipes.variedNodeRecipe), 26 | new ResearchPage(NodalRecipes.sameNodeRecipe)}) 27 | .setParents("NODEJAR", "NODETAPPER2").setParentsHidden("JARLABEL").setSpecial(); 28 | researchNodeCatalyzation.registerResearchItem(); 29 | 30 | ThaumcraftApi.addWarpToResearch("NODECATALYZATION", 2); 31 | ThaumcraftApi.addWarpToItem(new ItemStack(NodalItems.itemMatrix), 1); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/ItemApi.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.item.Item; 5 | import net.minecraft.item.ItemStack; 6 | import cpw.mods.fml.common.FMLLog; 7 | 8 | /** 9 | * @author Azanor 10 | * 11 | * This is used to gain access to the items in my mod. 12 | * I only give some examples and it will probably still 13 | * require a bit of work for you to get hold of everything you need. 14 | * 15 | */ 16 | public class ItemApi { 17 | 18 | public static ItemStack getItem(String itemString, int meta) { 19 | ItemStack item = null; 20 | 21 | try { 22 | String itemClass = "thaumcraft.common.config.ConfigItems"; 23 | Object obj = Class.forName(itemClass).getField(itemString).get(null); 24 | if (obj instanceof Item) { 25 | item = new ItemStack((Item) obj,1,meta); 26 | } else if (obj instanceof ItemStack) { 27 | item = (ItemStack) obj; 28 | } 29 | } catch (Exception ex) { 30 | FMLLog.warning("[Thaumcraft] Could not retrieve item identified by: " + itemString); 31 | } 32 | 33 | return item; 34 | } 35 | 36 | public static ItemStack getBlock(String itemString, int meta) { 37 | ItemStack item = null; 38 | 39 | try { 40 | String itemClass = "thaumcraft.common.config.ConfigBlocks"; 41 | Object obj = Class.forName(itemClass).getField(itemString).get(null); 42 | if (obj instanceof Block) { 43 | item = new ItemStack((Block) obj,1,meta); 44 | } else if (obj instanceof ItemStack) { 45 | item = (ItemStack) obj; 46 | } 47 | } catch (Exception ex) { 48 | FMLLog.warning("[Thaumcraft] Could not retrieve block identified by: " + itemString); 49 | } 50 | 51 | return item; 52 | } 53 | 54 | /** 55 | * 56 | * Some examples 57 | * 58 | * Casting Wands: 59 | * itemWandCasting 60 | * 61 | * Resources: 62 | * itemEssence, itemWispEssence, itemResource, itemShard, itemNugget, 63 | * itemNuggetChicken, itemNuggetBeef, itemNuggetPork, itemTripleMeatTreat 64 | * 65 | * Research: 66 | * itemResearchNotes, itemInkwell, itemThaumonomicon 67 | * 68 | */ 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/NodalMechanics.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics; 2 | 3 | import cpw.mods.fml.common.Mod; 4 | import cpw.mods.fml.common.SidedProxy; 5 | import cpw.mods.fml.common.event.FMLInitializationEvent; 6 | import cpw.mods.fml.common.event.FMLPostInitializationEvent; 7 | import cpw.mods.fml.common.event.FMLPreInitializationEvent; 8 | import net.minecraft.creativetab.CreativeTabs; 9 | import net.minecraft.util.StatCollector; 10 | import org.apache.logging.log4j.Logger; 11 | import shukaro.nodalmechanics.gui.NodalTab; 12 | import shukaro.nodalmechanics.items.NodalItems; 13 | import shukaro.nodalmechanics.net.CommonProxy; 14 | import shukaro.nodalmechanics.recipe.NodalRecipes; 15 | import shukaro.nodalmechanics.research.NodalResearch; 16 | 17 | @Mod(modid = NodalMechanics.modID, name = NodalMechanics.modName, version = NodalMechanics.modVersion, 18 | dependencies = "required-after:Thaumcraft") 19 | public class NodalMechanics 20 | { 21 | @SidedProxy(clientSide = "shukaro.nodalmechanics.net.ClientProxy", serverSide = "shukaro.nodalmechanics.net.CommonProxy") 22 | public static CommonProxy proxy; 23 | 24 | public static final String modID = "NodalMechanics"; 25 | public static final String modName = "NodalMechanics"; 26 | public static final String modVersion = "1.7.10R1.0"; 27 | 28 | public static Logger logger; 29 | 30 | public static CreativeTabs mainTab = new NodalTab(StatCollector.translateToLocal("nodalmechanics.tab")); 31 | 32 | @Mod.Instance(modID) 33 | public static NodalMechanics instance; 34 | 35 | @Mod.EventHandler 36 | public void preInit(FMLPreInitializationEvent evt) 37 | { 38 | logger = evt.getModLog(); 39 | NodalItems.initItems(); 40 | } 41 | 42 | @Mod.EventHandler 43 | public void init(FMLInitializationEvent evt) 44 | { 45 | NodalRecipes recipes = new NodalRecipes(); 46 | recipes.initRecipes(); 47 | proxy.init(); 48 | } 49 | 50 | @Mod.EventHandler 51 | public void postInit(FMLPostInitializationEvent evt) 52 | { 53 | NodalResearch.initResearch(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/potions/PotionFluxTaint.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.potions; 2 | 3 | import thaumcraft.api.damagesource.DamageSourceThaumcraft; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.potion.Potion; 8 | import net.minecraft.util.ResourceLocation; 9 | import thaumcraft.api.entities.ITaintedMob; 10 | import cpw.mods.fml.relauncher.Side; 11 | import cpw.mods.fml.relauncher.SideOnly; 12 | 13 | public class PotionFluxTaint extends Potion 14 | { 15 | public static PotionFluxTaint instance = null; // will be instantiated at runtime 16 | private int statusIconIndex = -1; 17 | 18 | public PotionFluxTaint(int par1, boolean par2, int par3) 19 | { 20 | super(par1,par2,par3); 21 | setIconIndex(0, 0); 22 | } 23 | 24 | public static void init() 25 | { 26 | instance.setPotionName("potion.fluxtaint"); 27 | instance.setIconIndex(3, 1); 28 | instance.setEffectiveness(0.25D); 29 | } 30 | 31 | @Override 32 | public boolean isBadEffect() { 33 | return true; 34 | } 35 | 36 | @Override 37 | @SideOnly(Side.CLIENT) 38 | public int getStatusIconIndex() { 39 | Minecraft.getMinecraft().renderEngine.bindTexture(rl); 40 | return super.getStatusIconIndex(); 41 | } 42 | 43 | static final ResourceLocation rl = new ResourceLocation("thaumcraft","textures/misc/potions.png"); 44 | 45 | @Override 46 | public void performEffect(EntityLivingBase target, int par2) { 47 | if (target instanceof ITaintedMob) { 48 | target.heal(1); 49 | } else 50 | if (!target.isEntityUndead() && !(target instanceof EntityPlayer)) 51 | { 52 | target.attackEntityFrom(DamageSourceThaumcraft.taint, 1); 53 | } 54 | else 55 | if (!target.isEntityUndead() && (target.getMaxHealth() > 1 || (target instanceof EntityPlayer))) 56 | { 57 | target.attackEntityFrom(DamageSourceThaumcraft.taint, 1); 58 | } 59 | } 60 | 61 | public boolean isReady(int par1, int par2) 62 | { 63 | int k = 40 >> par2; 64 | return k > 0 ? par1 % k == 0 : true; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/IWandFocus.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import thaumcraft.api.aspects.AspectList; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.IIcon; 7 | import net.minecraft.util.MovingObjectPosition; 8 | import net.minecraft.world.World; 9 | 10 | 11 | public interface IWandFocus { 12 | 13 | public enum WandFocusAnimation { 14 | WAVE, CHARGE; 15 | } 16 | 17 | /** 18 | * @return The color the focus should be changed to. 19 | */ 20 | public int getFocusColor(); 21 | 22 | /** 23 | * @return An icon that will be drawn as a block inside the focus "block". 24 | */ 25 | IIcon getFocusDepthLayerIcon(); 26 | 27 | public IIcon getOrnament(); 28 | 29 | public WandFocusAnimation getAnimation(); 30 | 31 | /** 32 | * Gets the amount of vis used per aspect per click or tick. This cost is actually listed as 33 | * a hundredth of a single point of vis, so a cost of 100 will equal one vis per tick/click. 34 | * It is returned as an AspectList to allow for multiple vis types in different ratios. 35 | */ 36 | public AspectList getVisCost(); 37 | 38 | public boolean isVisCostPerTick(); 39 | 40 | public ItemStack onFocusRightClick(ItemStack itemstack, World world, EntityPlayer player, MovingObjectPosition movingobjectposition); 41 | 42 | public void onUsingFocusTick(ItemStack itemstack, EntityPlayer player, int count); 43 | 44 | public void onPlayerStoppedUsingFocus(ItemStack itemstack, World world, EntityPlayer player, int count); 45 | 46 | /** 47 | * Helper method to determine in what order foci should be iterated through when 48 | * the user presses the 'change focus' keybinding. 49 | * @return a string of characters that foci will be sorted against. 50 | * For example AA00 will be placed before FG12 51 | *
As a guide build the sort string from two alphanumeric characters followed by 52 | * two numeric characters based on... whatever. 53 | */ 54 | public String getSortingHelper(ItemStack itemstack); 55 | 56 | boolean onFocusBlockStartBreak(ItemStack itemstack, int x, int y, int z, EntityPlayer player); 57 | 58 | public boolean acceptsEnchant(int id); 59 | 60 | 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/IAspectContainer.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | 4 | /** 5 | * 6 | * @author azanor 7 | * 8 | * Used by blocks like the crucible and alembic to hold their aspects. 9 | * Tiles extending this interface will have their aspects show up when viewed by goggles of revealing 10 | * 11 | */ 12 | public interface IAspectContainer { 13 | public AspectList getAspects(); 14 | 15 | 16 | public void setAspects(AspectList aspects); 17 | 18 | 19 | /** 20 | * This method is used to determine of a specific aspect can be added to this container. 21 | * @param tag 22 | * @return true or false 23 | */ 24 | public boolean doesContainerAccept(Aspect tag); 25 | 26 | /** 27 | * This method is used to add a certain amount of an aspect to the tile entity. 28 | * @param tag 29 | * @param amount 30 | * @return the amount of aspect left over that could not be added. 31 | */ 32 | public int addToContainer(Aspect tag, int amount); 33 | 34 | /** 35 | * Removes a certain amount of a specific aspect from the tile entity 36 | * @param tag 37 | * @param amount 38 | * @return true if that amount of aspect was available and was removed 39 | */ 40 | public boolean takeFromContainer(Aspect tag, int amount); 41 | 42 | /** 43 | * removes a bunch of different aspects and amounts from the tile entity. 44 | * @param ot the ObjectTags object that contains the aspects and their amounts. 45 | * @return true if all the aspects and their amounts were available and successfully removed 46 | * 47 | * Going away in the next major patch 48 | */ 49 | @Deprecated 50 | public boolean takeFromContainer(AspectList ot); 51 | 52 | /** 53 | * Checks if the tile entity contains the listed amount (or more) of the aspect 54 | * @param tag 55 | * @param amount 56 | * @return 57 | */ 58 | public boolean doesContainerContainAmount(Aspect tag,int amount); 59 | 60 | /** 61 | * Checks if the tile entity contains all the listed aspects and their amounts 62 | * @param ot the ObjectTags object that contains the aspects and their amounts. 63 | * @return 64 | * 65 | * Going away in the next major patch 66 | */ 67 | @Deprecated 68 | public boolean doesContainerContain(AspectList ot); 69 | 70 | /** 71 | * Returns how much of the aspect this tile entity contains 72 | * @param tag 73 | * @return the amount of that aspect found 74 | */ 75 | public int containerContains(Aspect tag); 76 | 77 | } 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/IEssentiaTransport.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | import net.minecraftforge.common.util.ForgeDirection; 4 | 5 | 6 | /** 7 | * @author Azanor 8 | * This interface is used by tiles that use or transport vis. 9 | * Only tiles that implement this interface will be able to connect to vis conduits or other thaumic devices 10 | */ 11 | public interface IEssentiaTransport { 12 | /** 13 | * Is this tile able to connect to other vis users/sources on the specified side? 14 | * @param face 15 | * @return 16 | */ 17 | public boolean isConnectable(ForgeDirection face); 18 | 19 | /** 20 | * Is this side used to input essentia? 21 | * @param face 22 | * @return 23 | */ 24 | boolean canInputFrom(ForgeDirection face); 25 | 26 | /** 27 | * Is this side used to output essentia? 28 | * @param face 29 | * @return 30 | */ 31 | boolean canOutputTo(ForgeDirection face); 32 | 33 | /** 34 | * Sets the amount of suction this block will apply 35 | * @param suction 36 | */ 37 | public void setSuction(Aspect aspect, int amount); 38 | 39 | /** 40 | * Returns the type of suction this block is applying. 41 | * @param loc 42 | * the location from where the suction is being checked 43 | * @return 44 | * a return type of null indicates the suction is untyped and the first thing available will be drawn 45 | */ 46 | public Aspect getSuctionType(ForgeDirection face); 47 | 48 | /** 49 | * Returns the strength of suction this block is applying. 50 | * @param loc 51 | * the location from where the suction is being checked 52 | * @return 53 | */ 54 | public int getSuctionAmount(ForgeDirection face); 55 | 56 | /** 57 | * remove the specified amount of essentia from this transport tile 58 | * @return how much was actually taken 59 | */ 60 | public int takeEssentia(Aspect aspect, int amount, ForgeDirection face); 61 | 62 | /** 63 | * add the specified amount of essentia to this transport tile 64 | * @return how much was actually added 65 | */ 66 | public int addEssentia(Aspect aspect, int amount, ForgeDirection face); 67 | 68 | /** 69 | * What type of essentia this contains 70 | * @param face 71 | * @return 72 | */ 73 | public Aspect getEssentiaType(ForgeDirection face); 74 | 75 | /** 76 | * How much essentia this block contains 77 | * @param face 78 | * @return 79 | */ 80 | public int getEssentiaAmount(ForgeDirection face); 81 | 82 | 83 | 84 | /** 85 | * Essentia will not be drawn from this container unless the suction exceeds this amount. 86 | * @return the amount 87 | */ 88 | public int getMinimumSuction(); 89 | 90 | /** 91 | * Return true if you want the conduit to extend a little further into the block. 92 | * Used by jars and alembics that have smaller than normal hitboxes 93 | * @return 94 | */ 95 | boolean renderExtendedTube(); 96 | 97 | 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/AspectSourceHelper.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import net.minecraft.tileentity.TileEntity; 6 | import net.minecraftforge.common.util.ForgeDirection; 7 | import cpw.mods.fml.common.FMLLog; 8 | 9 | public class AspectSourceHelper { 10 | 11 | static Method drainEssentia; 12 | static Method findEssentia; 13 | /** 14 | * This method is what is used to drain essentia from jars and other sources for things like 15 | * infusion crafting or powering the arcane furnace. A record of possible sources are kept track of 16 | * and refreshed as needed around the calling tile entity. This also renders the essentia trail particles. 17 | * Only 1 essentia is drained at a time 18 | * @param tile the tile entity that is draining the essentia 19 | * @param aspect the aspect that you are looking for 20 | * @param direction the direction from which you wish to drain. Forgedirection.Unknown simply seeks in all directions. 21 | * @param range how many blocks you wish to search for essentia sources. 22 | * @return boolean returns true if essentia was found and removed from a source. 23 | */ 24 | public static boolean drainEssentia(TileEntity tile, Aspect aspect, ForgeDirection direction, int range) { 25 | try { 26 | if(drainEssentia == null) { 27 | Class fake = Class.forName("thaumcraft.common.lib.events.EssentiaHandler"); 28 | drainEssentia = fake.getMethod("drainEssentia", TileEntity.class, Aspect.class, ForgeDirection.class, int.class); 29 | } 30 | return (Boolean) drainEssentia.invoke(null, tile, aspect, direction, range); 31 | } catch(Exception ex) { 32 | FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.events.EssentiaHandler method drainEssentia"); 33 | } 34 | return false; 35 | } 36 | 37 | /** 38 | * This method returns if there is any essentia of the passed type that can be drained. It in no way checks how 39 | * much there is, only if an essentia container nearby contains at least 1 point worth. 40 | * @param tile the tile entity that is checking the essentia 41 | * @param aspect the aspect that you are looking for 42 | * @param direction the direction from which you wish to drain. Forgedirection.Unknown simply seeks in all directions. 43 | * @param range how many blocks you wish to search for essentia sources. 44 | * @return boolean returns true if essentia was found and removed from a source. 45 | */ 46 | public static boolean findEssentia(TileEntity tile, Aspect aspect, ForgeDirection direction, int range) { 47 | try { 48 | if(findEssentia == null) { 49 | Class fake = Class.forName("thaumcraft.common.lib.events.EssentiaHandler"); 50 | findEssentia = fake.getMethod("findEssentia", TileEntity.class, Aspect.class, ForgeDirection.class, int.class); 51 | } 52 | return (Boolean) findEssentia.invoke(null, tile, aspect, direction, range); 53 | } catch(Exception ex) { 54 | FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.events.EssentiaHandler method findEssentia"); 55 | } 56 | return false; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/research/ResearchCategories.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.research; 2 | 3 | import java.util.Collection; 4 | import java.util.LinkedHashMap; 5 | 6 | import net.minecraft.util.ResourceLocation; 7 | import net.minecraft.util.StatCollector; 8 | 9 | import org.apache.logging.log4j.Level; 10 | 11 | import cpw.mods.fml.common.FMLLog; 12 | 13 | public class ResearchCategories { 14 | 15 | //Research 16 | public static LinkedHashMap researchCategories = new LinkedHashMap (); 17 | 18 | /** 19 | * @param key 20 | * @return the research item linked to this key 21 | */ 22 | public static ResearchCategoryList getResearchList(String key) { 23 | return researchCategories.get(key); 24 | } 25 | 26 | /** 27 | * @param key 28 | * @return the name of the research category linked to this key. 29 | * Must be stored as localization information in the LanguageRegistry. 30 | */ 31 | public static String getCategoryName(String key) { 32 | return StatCollector.translateToLocal("tc.research_category."+key); 33 | } 34 | 35 | /** 36 | * @param key the research key 37 | * @return the ResearchItem object. 38 | */ 39 | public static ResearchItem getResearch(String key) { 40 | Collection rc = researchCategories.values(); 41 | for (Object cat:rc) { 42 | Collection rl = ((ResearchCategoryList)cat).research.values(); 43 | for (Object ri:rl) { 44 | if ((((ResearchItem)ri).key).equals(key)) return (ResearchItem)ri; 45 | } 46 | } 47 | return null; 48 | } 49 | 50 | /** 51 | * This should only be done at the PostInit stage 52 | * @param key the key used for this category 53 | * @param icon the icon to be used for the research category tab 54 | * @param background the resource location of the background image to use for this category 55 | * @return the name of the research linked to this key 56 | */ 57 | public static void registerCategory(String key, ResourceLocation icon, ResourceLocation background) { 58 | if (getResearchList(key)==null) { 59 | ResearchCategoryList rl = new ResearchCategoryList(icon, background); 60 | researchCategories.put(key, rl); 61 | } 62 | } 63 | 64 | public static void addResearch(ResearchItem ri) { 65 | ResearchCategoryList rl = getResearchList(ri.category); 66 | if (rl!=null && !rl.research.containsKey(ri.key)) { 67 | 68 | if (!ri.isVirtual()) { 69 | for (ResearchItem rr:rl.research.values()) { 70 | if (rr.displayColumn == ri.displayColumn && rr.displayRow == ri.displayRow) { 71 | FMLLog.log(Level.FATAL, "[Thaumcraft] Research ["+ri.getName()+"] not added as it overlaps with existing research ["+rr.getName()+"]"); 72 | return; 73 | } 74 | } 75 | } 76 | 77 | 78 | rl.research.put(ri.key, ri); 79 | 80 | if (ri.displayColumn < rl.minDisplayColumn) 81 | { 82 | rl.minDisplayColumn = ri.displayColumn; 83 | } 84 | 85 | if (ri.displayRow < rl.minDisplayRow) 86 | { 87 | rl.minDisplayRow = ri.displayRow; 88 | } 89 | 90 | if (ri.displayColumn > rl.maxDisplayColumn) 91 | { 92 | rl.maxDisplayColumn = ri.displayColumn; 93 | } 94 | 95 | if (ri.displayRow > rl.maxDisplayRow) 96 | { 97 | rl.maxDisplayRow = ri.displayRow; 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/WorldCoordinates.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | import net.minecraft.tileentity.TileEntity; 5 | 6 | public class WorldCoordinates implements Comparable 7 | { 8 | public int x; 9 | 10 | /** the y coordinate */ 11 | public int y; 12 | 13 | /** the z coordinate */ 14 | public int z; 15 | 16 | public int dim; 17 | 18 | public WorldCoordinates() {} 19 | 20 | public WorldCoordinates(int par1, int par2, int par3, int d) 21 | { 22 | this.x = par1; 23 | this.y = par2; 24 | this.z = par3; 25 | this.dim = d; 26 | } 27 | 28 | public WorldCoordinates(TileEntity tile) 29 | { 30 | this.x = tile.xCoord; 31 | this.y = tile.yCoord; 32 | this.z = tile.zCoord; 33 | this.dim = tile.getWorldObj().provider.dimensionId; 34 | } 35 | 36 | public WorldCoordinates(WorldCoordinates par1ChunkCoordinates) 37 | { 38 | this.x = par1ChunkCoordinates.x; 39 | this.y = par1ChunkCoordinates.y; 40 | this.z = par1ChunkCoordinates.z; 41 | this.dim = par1ChunkCoordinates.dim; 42 | } 43 | 44 | public boolean equals(Object par1Obj) 45 | { 46 | if (!(par1Obj instanceof WorldCoordinates)) 47 | { 48 | return false; 49 | } 50 | else 51 | { 52 | WorldCoordinates coordinates = (WorldCoordinates)par1Obj; 53 | return this.x == coordinates.x && this.y == coordinates.y && this.z == coordinates.z && this.dim == coordinates.dim ; 54 | } 55 | } 56 | 57 | public int hashCode() 58 | { 59 | return this.x + this.y << 8 + this.z << 16 + this.dim << 24; 60 | } 61 | 62 | /** 63 | * Compare the coordinate with another coordinate 64 | */ 65 | public int compareWorldCoordinate(WorldCoordinates par1) 66 | { 67 | return this.dim == par1.dim ? ( 68 | this.y == par1.y ? (this.z == par1.z ? this.x - par1.x : this.z - par1.z) : this.y - par1.y) : -1; 69 | } 70 | 71 | public void set(int par1, int par2, int par3, int d) 72 | { 73 | this.x = par1; 74 | this.y = par2; 75 | this.z = par3; 76 | this.dim = d; 77 | } 78 | 79 | /** 80 | * Returns the squared distance between this coordinates and the coordinates given as argument. 81 | */ 82 | public float getDistanceSquared(int par1, int par2, int par3) 83 | { 84 | float f = (float)(this.x - par1); 85 | float f1 = (float)(this.y - par2); 86 | float f2 = (float)(this.z - par3); 87 | return f * f + f1 * f1 + f2 * f2; 88 | } 89 | 90 | /** 91 | * Return the squared distance between this coordinates and the ChunkCoordinates given as argument. 92 | */ 93 | public float getDistanceSquaredToWorldCoordinates(WorldCoordinates par1ChunkCoordinates) 94 | { 95 | return this.getDistanceSquared(par1ChunkCoordinates.x, par1ChunkCoordinates.y, par1ChunkCoordinates.z); 96 | } 97 | 98 | public int compareTo(Object par1Obj) 99 | { 100 | return this.compareWorldCoordinate((WorldCoordinates)par1Obj); 101 | } 102 | 103 | public void readNBT(NBTTagCompound nbt) { 104 | this.x = nbt.getInteger("w_x"); 105 | this.y = nbt.getInteger("w_y"); 106 | this.z = nbt.getInteger("w_z"); 107 | this.dim = nbt.getInteger("w_d"); 108 | } 109 | 110 | public void writeNBT(NBTTagCompound nbt) { 111 | nbt.setInteger("w_x",x); 112 | nbt.setInteger("w_y",y); 113 | nbt.setInteger("w_z",z); 114 | nbt.setInteger("w_d",dim); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/CrucibleRecipe.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import java.util.ArrayList; 4 | 5 | import thaumcraft.api.aspects.Aspect; 6 | import thaumcraft.api.aspects.AspectList; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraftforge.oredict.OreDictionary; 9 | import thaumcraft.api.ThaumcraftApiHelper; 10 | 11 | public class CrucibleRecipe { 12 | 13 | private ItemStack recipeOutput; 14 | 15 | public Object catalyst; 16 | public AspectList aspects; 17 | public String key; 18 | 19 | public int hash; 20 | 21 | public CrucibleRecipe(String researchKey, ItemStack result, Object cat, AspectList tags) { 22 | recipeOutput = result; 23 | this.aspects = tags; 24 | this.key = researchKey; 25 | this.catalyst = cat; 26 | if (cat instanceof String) { 27 | this.catalyst = OreDictionary.getOres((String) cat); 28 | } 29 | String hc = researchKey + result.toString(); 30 | for (Aspect tag:tags.getAspects()) { 31 | hc += tag.getTag()+tags.getAmount(tag); 32 | } 33 | if (cat instanceof ItemStack) { 34 | hc += ((ItemStack)cat).toString(); 35 | } else 36 | if (cat instanceof ArrayList && ((ArrayList)catalyst).size()>0) { 37 | for (ItemStack is :(ArrayList)catalyst) { 38 | hc += is.toString(); 39 | } 40 | } 41 | 42 | hash = hc.hashCode(); 43 | } 44 | 45 | 46 | 47 | public boolean matches(AspectList itags, ItemStack cat) { 48 | if (catalyst instanceof ItemStack && 49 | !ThaumcraftApiHelper.itemMatches((ItemStack) catalyst,cat,false)) { 50 | return false; 51 | } else 52 | if (catalyst instanceof ArrayList && ((ArrayList)catalyst).size()>0) { 53 | ItemStack[] ores = ((ArrayList)catalyst).toArray(new ItemStack[]{}); 54 | if (!ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{cat},ores)) return false; 55 | } 56 | if (itags==null) return false; 57 | for (Aspect tag:aspects.getAspects()) { 58 | if (itags.getAmount(tag))catalyst).size()>0) { 68 | ItemStack[] ores = ((ArrayList)catalyst).toArray(new ItemStack[]{}); 69 | if (ThaumcraftApiHelper.containsMatch(false, new ItemStack[]{cat},ores)) return true; 70 | } 71 | return false; 72 | } 73 | 74 | public AspectList removeMatching(AspectList itags) { 75 | AspectList temptags = new AspectList(); 76 | temptags.aspects.putAll(itags.aspects); 77 | 78 | for (Aspect tag:aspects.getAspects()) { 79 | temptags.remove(tag, aspects.getAmount(tag)); 80 | // if (!temptags.remove(tag, aspects.getAmount(tag))) return null; 81 | } 82 | 83 | itags = temptags; 84 | return itags; 85 | } 86 | 87 | public ItemStack getRecipeOutput() { 88 | return recipeOutput; 89 | } 90 | 91 | 92 | // @Override 93 | // public int hashCode() { 94 | // String hash = ""; 95 | // if (catalyst instanceof ItemStack) { 96 | // hash += ((ItemStack)catalyst).toString(); 97 | // } else if (catalyst instanceof ArrayList && ((ArrayList)catalyst).size()>0) { 98 | // for (ItemStack s:(ArrayList)catalyst) { 99 | // hash += s.toString(); 100 | // } 101 | // } else { 102 | // hash += catalyst.hashCode(); 103 | // } 104 | // hash += getRecipeOutput().toString(); 105 | // for (Aspect a:aspects.getAspectsSorted()) { 106 | // hash += a.getTag() + aspects.getAmount(a); 107 | // } 108 | // return hash.hashCode(); 109 | // } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/WandCap.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.List; 5 | 6 | import thaumcraft.api.aspects.Aspect; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.util.ResourceLocation; 9 | 10 | /** 11 | * This class is used to keep the material information for the various caps. 12 | * It is also used to generate the wand recipes ingame. 13 | * @author Azanor 14 | * 15 | */ 16 | public class WandCap { 17 | 18 | private String tag; 19 | 20 | /** 21 | * Cost to craft this wand. Combined with the rod cost. 22 | */ 23 | private int craftCost; 24 | 25 | /** 26 | * the amount by which all aspect costs are multiplied 27 | */ 28 | float baseCostModifier; 29 | 30 | /** 31 | * specifies a list of primal aspects that use the special discount figure instead of the normal discount. 32 | */ 33 | List specialCostModifierAspects; 34 | 35 | /** 36 | * the amount by which the specified aspect costs are multiplied 37 | */ 38 | float specialCostModifier; 39 | 40 | /** 41 | * The texture that will be used for the ingame wand cap 42 | */ 43 | ResourceLocation texture; 44 | 45 | /** 46 | * the actual item that makes up this cap and will be used to generate the wand recipes 47 | */ 48 | ItemStack item; 49 | 50 | public static LinkedHashMap caps = new LinkedHashMap(); 51 | 52 | public WandCap (String tag, float discount, ItemStack item, int craftCost) { 53 | this.setTag(tag); 54 | this.baseCostModifier = discount; 55 | this.specialCostModifierAspects = null; 56 | texture = new ResourceLocation("thaumcraft","textures/models/wand_cap_"+getTag()+".png"); 57 | this.item=item; 58 | this.setCraftCost(craftCost); 59 | caps.put(tag, this); 60 | } 61 | 62 | public WandCap (String tag, float discount, List specialAspects, float discountSpecial, ItemStack item, int craftCost) { 63 | this.setTag(tag); 64 | this.baseCostModifier = discount; 65 | this.specialCostModifierAspects = specialAspects; 66 | this.specialCostModifier = discountSpecial; 67 | texture = new ResourceLocation("thaumcraft","textures/models/wand_cap_"+getTag()+".png"); 68 | this.item=item; 69 | this.setCraftCost(craftCost); 70 | caps.put(tag, this); 71 | } 72 | 73 | public float getBaseCostModifier() { 74 | return baseCostModifier; 75 | } 76 | 77 | public List getSpecialCostModifierAspects() { 78 | return specialCostModifierAspects; 79 | } 80 | 81 | public float getSpecialCostModifier() { 82 | return specialCostModifier; 83 | } 84 | 85 | public ResourceLocation getTexture() { 86 | return texture; 87 | } 88 | 89 | public void setTexture(ResourceLocation texture) { 90 | this.texture = texture; 91 | } 92 | 93 | public String getTag() { 94 | return tag; 95 | } 96 | 97 | public void setTag(String tag) { 98 | this.tag = tag; 99 | } 100 | 101 | 102 | public ItemStack getItem() { 103 | return item; 104 | } 105 | 106 | public void setItem(ItemStack item) { 107 | this.item = item; 108 | } 109 | 110 | public int getCraftCost() { 111 | return craftCost; 112 | } 113 | 114 | public void setCraftCost(int craftCost) { 115 | this.craftCost = craftCost; 116 | } 117 | 118 | /** 119 | * The research a player needs to have finished to be able to craft a wand with this cap. 120 | */ 121 | public String getResearch() { 122 | return "CAP_"+getTag(); 123 | } 124 | 125 | // Some examples: 126 | // WandCap WAND_CAP_IRON = new WandCap("iron", 1.1f, Arrays.asList(Aspect.ORDER),1, new ItemStack(ConfigItems.itemWandCap,1,0),1); 127 | // WandCap WAND_CAP_GOLD = new WandCap("gold", 1f, new ItemStack(ConfigItems.itemWandCap,1,1),3); 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/InfusionRecipe.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import java.util.ArrayList; 4 | 5 | import thaumcraft.api.aspects.AspectList; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.world.World; 9 | import net.minecraftforge.oredict.OreDictionary; 10 | import thaumcraft.api.ThaumcraftApiHelper; 11 | 12 | public class InfusionRecipe 13 | { 14 | protected AspectList aspects; 15 | protected String research; 16 | private ItemStack[] components; 17 | private ItemStack recipeInput; 18 | protected Object recipeOutput; 19 | protected int instability; 20 | 21 | public InfusionRecipe(String research, Object output, int inst, 22 | AspectList aspects2, ItemStack input, ItemStack[] recipe) { 23 | this.research = research; 24 | this.recipeOutput = output; 25 | this.recipeInput = input; 26 | this.aspects = aspects2; 27 | this.components = recipe; 28 | this.instability = inst; 29 | } 30 | 31 | /** 32 | * Used to check if a recipe matches current crafting inventory 33 | * @param player 34 | */ 35 | public boolean matches(ArrayList input, ItemStack central, World world, EntityPlayer player) { 36 | if (getRecipeInput()==null) return false; 37 | 38 | if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) { 39 | return false; 40 | } 41 | 42 | ItemStack i2 = central.copy(); 43 | if (getRecipeInput().getItemDamage()==OreDictionary.WILDCARD_VALUE) { 44 | i2.setItemDamage(OreDictionary.WILDCARD_VALUE); 45 | } 46 | 47 | if (!areItemStacksEqual(i2, getRecipeInput(), true)) return false; 48 | 49 | ArrayList ii = new ArrayList(); 50 | for (ItemStack is:input) { 51 | ii.add(is.copy()); 52 | } 53 | 54 | for (ItemStack comp:getComponents()) { 55 | boolean b=false; 56 | for (int a=0;a stack0.getMaxStackSize() ? false : t1)); 90 | } 91 | 92 | 93 | public Object getRecipeOutput() { 94 | return getRecipeOutput(this.getRecipeInput()); 95 | } 96 | 97 | public AspectList getAspects() { 98 | return getAspects(this.getRecipeInput()); 99 | } 100 | 101 | public int getInstability() { 102 | return getInstability(this.getRecipeInput()); 103 | } 104 | 105 | public String getResearch() { 106 | return research; 107 | } 108 | 109 | public ItemStack getRecipeInput() { 110 | return recipeInput; 111 | } 112 | 113 | public ItemStack[] getComponents() { 114 | return components; 115 | } 116 | 117 | public Object getRecipeOutput(ItemStack input) { 118 | return recipeOutput; 119 | } 120 | 121 | public AspectList getAspects(ItemStack input) { 122 | return aspects; 123 | } 124 | 125 | public int getInstability(ItemStack input) { 126 | return instability; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/WandRod.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.util.ResourceLocation; 7 | 8 | /** 9 | * 10 | * @author Azanor 11 | * 12 | * This class is used to keep the material information for the various rods. 13 | * It is also used to generate the wand recipes ingame. 14 | * 15 | */ 16 | public class WandRod { 17 | 18 | 19 | private String tag; 20 | 21 | /** 22 | * Cost to craft this wand. Combined with the rod cost. 23 | */ 24 | private int craftCost; 25 | 26 | /** 27 | * The amount of vis that can be stored - this number is actually multiplied 28 | * by 100 for use by the wands internals 29 | */ 30 | int capacity; 31 | 32 | /** 33 | * The texture that will be used for the ingame wand rod 34 | */ 35 | protected ResourceLocation texture; 36 | 37 | /** 38 | * the actual item that makes up this rod and will be used to generate the wand recipes 39 | */ 40 | ItemStack item; 41 | 42 | /** 43 | * A class that will be called whenever the wand onUpdate tick is run 44 | */ 45 | IWandRodOnUpdate onUpdate; 46 | 47 | /** 48 | * Does the rod glow in the dark? 49 | */ 50 | boolean glow; 51 | 52 | public static LinkedHashMap rods = new LinkedHashMap(); 53 | 54 | public WandRod (String tag, int capacity, ItemStack item, int craftCost, ResourceLocation texture) { 55 | this.setTag(tag); 56 | this.capacity = capacity; 57 | this.texture = texture; 58 | this.item=item; 59 | this.setCraftCost(craftCost); 60 | rods.put(tag, this); 61 | } 62 | 63 | public WandRod (String tag, int capacity, ItemStack item, int craftCost, IWandRodOnUpdate onUpdate, ResourceLocation texture) { 64 | this.setTag(tag); 65 | this.capacity = capacity; 66 | this.texture = texture; 67 | this.item=item; 68 | this.setCraftCost(craftCost); 69 | rods.put(tag, this); 70 | this.onUpdate = onUpdate; 71 | } 72 | 73 | public WandRod (String tag, int capacity, ItemStack item, int craftCost) { 74 | this.setTag(tag); 75 | this.capacity = capacity; 76 | this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+getTag()+".png"); 77 | this.item=item; 78 | this.setCraftCost(craftCost); 79 | rods.put(tag, this); 80 | } 81 | 82 | public WandRod (String tag, int capacity, ItemStack item, int craftCost, IWandRodOnUpdate onUpdate) { 83 | this.setTag(tag); 84 | this.capacity = capacity; 85 | this.texture = new ResourceLocation("thaumcraft","textures/models/wand_rod_"+getTag()+".png"); 86 | this.item=item; 87 | this.setCraftCost(craftCost); 88 | rods.put(tag, this); 89 | this.onUpdate = onUpdate; 90 | } 91 | 92 | public String getTag() { 93 | return tag; 94 | } 95 | 96 | public void setTag(String tag) { 97 | this.tag = tag; 98 | } 99 | 100 | public int getCapacity() { 101 | return capacity; 102 | } 103 | 104 | public void setCapacity(int capacity) { 105 | this.capacity = capacity; 106 | } 107 | 108 | public ResourceLocation getTexture() { 109 | return texture; 110 | } 111 | 112 | public void setTexture(ResourceLocation texture) { 113 | this.texture = texture; 114 | } 115 | 116 | public ItemStack getItem() { 117 | return item; 118 | } 119 | 120 | public void setItem(ItemStack item) { 121 | this.item = item; 122 | } 123 | 124 | public int getCraftCost() { 125 | return craftCost; 126 | } 127 | 128 | public void setCraftCost(int craftCost) { 129 | this.craftCost = craftCost; 130 | } 131 | 132 | public IWandRodOnUpdate getOnUpdate() { 133 | return onUpdate; 134 | } 135 | 136 | public void setOnUpdate(IWandRodOnUpdate onUpdate) { 137 | this.onUpdate = onUpdate; 138 | } 139 | 140 | public boolean isGlowing() { 141 | return glow; 142 | } 143 | 144 | public void setGlowing(boolean hasGlow) { 145 | this.glow = hasGlow; 146 | } 147 | 148 | /** 149 | * The research a player needs to have finished to be able to craft a wand with this rod. 150 | */ 151 | public String getResearch() { 152 | return "ROD_"+getTag(); 153 | } 154 | 155 | // Some examples: 156 | // WandRod WAND_ROD_WOOD = new WandRod("wood",25,new ItemStack(Item.stick),1); 157 | // WandRod WAND_ROD_BLAZE = new WandRod("blaze",100,new ItemStack(Item.blazeRod),7,new WandRodBlazeOnUpdate()); 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/items/ItemMatrix.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.items; 2 | 3 | import cpw.mods.fml.relauncher.Side; 4 | import cpw.mods.fml.relauncher.SideOnly; 5 | import gnu.trove.map.TMap; 6 | import gnu.trove.map.hash.THashMap; 7 | import net.minecraft.client.renderer.texture.IIconRegister; 8 | import net.minecraft.creativetab.CreativeTabs; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.EnumRarity; 11 | import net.minecraft.item.Item; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.nbt.NBTTagCompound; 14 | import net.minecraft.util.IIcon; 15 | import net.minecraft.util.StatCollector; 16 | import org.apache.commons.lang3.text.WordUtils; 17 | import shukaro.nodalmechanics.NodalMechanics; 18 | import shukaro.nodalmechanics.util.FormatCodes; 19 | import thaumcraft.api.aspects.Aspect; 20 | 21 | import java.util.List; 22 | import java.util.Locale; 23 | 24 | public class ItemMatrix extends Item 25 | { 26 | private IIcon icon; 27 | 28 | public ItemMatrix() 29 | { 30 | super(); 31 | this.setHasSubtypes(true); 32 | this.setCreativeTab(NodalMechanics.mainTab); 33 | this.setUnlocalizedName("nodalmechanics.matrix"); 34 | } 35 | 36 | @Override 37 | public String getUnlocalizedName(ItemStack stack) 38 | { 39 | if (stack.hasTagCompound()) 40 | return this.getUnlocalizedName() + ".attuned"; 41 | else 42 | return this.getUnlocalizedName() + ".unattuned"; 43 | } 44 | 45 | @Override 46 | @SideOnly(Side.CLIENT) 47 | public void getSubItems(Item id, CreativeTabs tab, List list) 48 | { 49 | list.add(new ItemStack(id, 1, 0)); 50 | for (Aspect aspect : Aspect.getPrimalAspects()) 51 | { 52 | ItemStack stack = new ItemStack(id, 1, 0); 53 | NBTTagCompound tag = new NBTTagCompound(); 54 | tag.setString("aspects", multiplyAspect(aspect.getTag())); 55 | stack.setTagCompound(tag); 56 | list.add(stack); 57 | } 58 | } 59 | 60 | private String multiplyAspect(String aspect) 61 | { 62 | return aspect + "," + aspect + "," + aspect + "," + aspect + "," + aspect + "," + aspect + "," + aspect + "," + aspect; 63 | } 64 | 65 | @Override 66 | @SideOnly(Side.CLIENT) 67 | public IIcon getIconFromDamage(int meta) 68 | { 69 | return this.icon; 70 | } 71 | 72 | @Override 73 | @SideOnly(Side.CLIENT) 74 | public void registerIcons(IIconRegister reg) 75 | { 76 | this.icon = reg.registerIcon(NodalMechanics.modID.toLowerCase(Locale.ENGLISH) + ":" + "itemMatrix"); 77 | } 78 | 79 | @Override 80 | @SideOnly(Side.CLIENT) 81 | public EnumRarity getRarity(ItemStack stack) 82 | { 83 | return stack.hasTagCompound() ? EnumRarity.uncommon : EnumRarity.common; 84 | } 85 | 86 | @Override 87 | @SideOnly(Side.CLIENT) 88 | public boolean hasEffect(ItemStack stack, int pass) 89 | { 90 | return stack.hasTagCompound(); 91 | } 92 | 93 | @Override 94 | @SideOnly(Side.CLIENT) 95 | public void addInformation(ItemStack stack, EntityPlayer player, List infoList, boolean advancedTooltips) 96 | { 97 | if (stack.hasTagCompound() && stack.getTagCompound().hasKey("aspects")) 98 | { 99 | TMap aspectMap = new THashMap(); 100 | for (String s : stack.getTagCompound().getString("aspects").split(",")) 101 | { 102 | if (!aspectMap.containsKey(s)) 103 | aspectMap.put(s, 1); 104 | else 105 | aspectMap.put(s, aspectMap.get(s) + 1); 106 | } 107 | for (String s : aspectMap.keySet()) 108 | infoList.add("\u00A7" + (Aspect.getAspect(s).getChatcolor() != null ? Aspect.getAspect(s).getChatcolor() : "7") + WordUtils.capitalize(s) + FormatCodes.Reset.code + FormatCodes.White.code + " x " + aspectMap.get(s)); 109 | 110 | infoList.add(FormatCodes.DarkGrey.code + FormatCodes.Italic.code + StatCollector.translateToLocal("tooltip.nodalmechanics.matrix.attuned")); 111 | } 112 | else 113 | infoList.add(FormatCodes.DarkGrey.code + FormatCodes.Italic.code + StatCollector.translateToLocal("tooltip.nodalmechanics.matrix.unattuned")); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/ItemFocusBasic.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import java.text.DecimalFormat; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import thaumcraft.api.aspects.AspectList; 8 | import net.minecraft.enchantment.EnchantmentHelper; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.item.EnumRarity; 11 | import net.minecraft.item.Item; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.util.IIcon; 14 | import net.minecraft.util.MovingObjectPosition; 15 | import net.minecraft.util.StatCollector; 16 | import net.minecraft.world.World; 17 | import thaumcraft.api.ThaumcraftApi; 18 | import thaumcraft.api.aspects.Aspect; 19 | import cpw.mods.fml.relauncher.Side; 20 | import cpw.mods.fml.relauncher.SideOnly; 21 | 22 | public class ItemFocusBasic extends Item implements IWandFocus { 23 | 24 | public ItemFocusBasic () 25 | { 26 | super(); 27 | maxStackSize = 1; 28 | canRepair=false; 29 | this.setMaxDamage(0); 30 | } 31 | 32 | public IIcon icon; 33 | 34 | @SideOnly(Side.CLIENT) 35 | @Override 36 | public IIcon getIconFromDamage(int par1) { 37 | return icon; 38 | } 39 | 40 | @Override 41 | public boolean isItemTool(ItemStack par1ItemStack) 42 | { 43 | return true; 44 | } 45 | 46 | @Override 47 | public boolean isDamageable() { 48 | return true; 49 | } 50 | 51 | @Override 52 | public void addInformation(ItemStack stack,EntityPlayer player, List list, boolean par4) { 53 | AspectList al = this.getVisCost(); 54 | if (al!=null && al.size()>0) { 55 | list.add(StatCollector.translateToLocal(isVisCostPerTick()?"item.Focus.cost2":"item.Focus.cost1")); 56 | for (Aspect aspect:al.getAspectsSorted()) { 57 | DecimalFormat myFormatter = new DecimalFormat("#####.##"); 58 | String amount = myFormatter.format(al.getAmount(aspect)/100f); 59 | list.add(" \u00A7"+aspect.getChatcolor()+aspect.getName()+"\u00A7r x "+ amount); 60 | 61 | } 62 | } 63 | } 64 | 65 | @Override 66 | public int getItemEnchantability() { 67 | return 5; 68 | } 69 | 70 | @Override 71 | public EnumRarity getRarity(ItemStack itemstack) 72 | { 73 | return EnumRarity.rare; 74 | } 75 | 76 | 77 | @Override 78 | public int getFocusColor() { 79 | // TODO Auto-generated method stub 80 | return 0; 81 | } 82 | 83 | @Override 84 | public AspectList getVisCost() { 85 | // TODO Auto-generated method stub 86 | return null; 87 | } 88 | 89 | @Override 90 | public ItemStack onFocusRightClick(ItemStack itemstack, World world, 91 | EntityPlayer player, MovingObjectPosition movingobjectposition) { 92 | // TODO Auto-generated method stub 93 | return null; 94 | } 95 | 96 | @Override 97 | public void onUsingFocusTick(ItemStack itemstack, EntityPlayer player, 98 | int count) { 99 | // TODO Auto-generated method stub 100 | } 101 | 102 | @Override 103 | public void onPlayerStoppedUsingFocus(ItemStack itemstack, World world, 104 | EntityPlayer player, int count) { 105 | // TODO Auto-generated method stub 106 | 107 | } 108 | 109 | /** 110 | * Just insert two alphanumeric characters before this string in your focus item class 111 | */ 112 | @Override 113 | public String getSortingHelper(ItemStack itemstack) { 114 | Map ench = EnchantmentHelper.getEnchantments(itemstack); 115 | String out=""; 116 | for (Integer lvl:ench.values()) { 117 | out = out + lvl + ""; 118 | } 119 | return out; 120 | } 121 | 122 | @Override 123 | public boolean isVisCostPerTick() { 124 | return false; 125 | } 126 | 127 | @Override 128 | public IIcon getOrnament() { 129 | // TODO Auto-generated method stub 130 | return null; 131 | } 132 | 133 | @Override 134 | public boolean onFocusBlockStartBreak(ItemStack itemstack, int x, int y, 135 | int z, EntityPlayer player) { 136 | // TODO Auto-generated method stub 137 | return false; 138 | } 139 | 140 | @Override 141 | public WandFocusAnimation getAnimation() { 142 | return WandFocusAnimation.WAVE; 143 | } 144 | 145 | @Override 146 | public IIcon getFocusDepthLayerIcon() { 147 | // TODO Auto-generated method stub 148 | return null; 149 | } 150 | 151 | /** 152 | * @see IWandFocus#acceptsEnchant(int) 153 | * By default fortune is off for all wands 154 | **/ 155 | @Override 156 | public boolean acceptsEnchant(int id) { 157 | if (id==ThaumcraftApi.enchantFrugal|| 158 | id==ThaumcraftApi.enchantPotency) return true; 159 | return false; 160 | } 161 | 162 | 163 | 164 | 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/recipe/RecipeNode.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.recipe; 2 | 3 | import gnu.trove.map.TMap; 4 | import gnu.trove.map.hash.THashMap; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import net.minecraft.world.World; 9 | import net.minecraftforge.oredict.OreDictionary; 10 | import shukaro.nodalmechanics.items.NodalItems; 11 | import thaumcraft.api.ItemApi; 12 | import thaumcraft.api.ThaumcraftApiHelper; 13 | import thaumcraft.api.aspects.Aspect; 14 | import thaumcraft.api.aspects.AspectList; 15 | import thaumcraft.api.crafting.InfusionRecipe; 16 | 17 | import java.util.ArrayList; 18 | import java.util.Random; 19 | 20 | public class RecipeNode extends InfusionRecipe 21 | { 22 | public static final int VISMULTIPLIER = 10; 23 | public static final int INSTABILITY = 10; 24 | public static Random rand; 25 | 26 | public RecipeNode() 27 | { 28 | super("NODECATALYZATION", ItemApi.getItem("itemJarNode", 0), INSTABILITY, new AspectList(), new ItemStack(NodalItems.itemMatrix), new ItemStack[]{ItemApi.getItem("itemResource", 14), ItemApi.getItem("itemResource", 14)}); 29 | rand = new Random(); 30 | } 31 | 32 | @Override 33 | public boolean matches(ArrayList input, ItemStack central, World world, EntityPlayer player) 34 | { 35 | if (!ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), getResearch())) 36 | return false; 37 | if (input == null || input.size() != 2) 38 | return false; 39 | if (!checkItemEquals(input.get(0), getComponents()[0]) || !checkItemEquals(input.get(1), getComponents()[1])) 40 | return false; 41 | ((ItemStack)this.recipeOutput).setTagCompound(new NBTTagCompound()); 42 | if (central != null && central.getItem().equals(NodalItems.itemMatrix)) 43 | { 44 | if (central.hasTagCompound() && central.getTagCompound().hasKey("aspects")) 45 | { 46 | TMap aspectMap = new THashMap(); 47 | for (String s : central.getTagCompound().getString("aspects").split(",")) 48 | { 49 | if (!aspectMap.containsKey(s)) 50 | aspectMap.put(s, 1); 51 | else 52 | aspectMap.put(s, aspectMap.get(s) + 1); 53 | } 54 | this.aspects = new AspectList(); 55 | AspectList smallAspects = new AspectList(); 56 | for (String s : aspectMap.keySet()) 57 | { 58 | this.aspects.add(Aspect.getAspect(s), aspectMap.get(s) * 15 * VISMULTIPLIER); 59 | smallAspects.add(Aspect.getAspect(s), aspectMap.get(s) * 15); 60 | } 61 | smallAspects.writeToNBT(((ItemStack)this.recipeOutput).getTagCompound()); 62 | ((ItemStack)this.recipeOutput).getTagCompound().setInteger("nodetype", getNodeType()); 63 | if (rand.nextInt(100) < 60) 64 | ((ItemStack)this.recipeOutput).getTagCompound().setInteger("nodemod", getNodeMod()); 65 | return true; 66 | } 67 | } 68 | return false; 69 | } 70 | 71 | private int getNodeType() 72 | { 73 | int roll = rand.nextInt(100); 74 | if (roll < 80) 75 | return 0; 76 | else if (roll < 90) 77 | { 78 | if (roll < 85) 79 | return 1; 80 | else if (roll < 90) 81 | return 4; 82 | } 83 | else 84 | { 85 | if (roll < 93) 86 | return 2; 87 | else if (roll < 96) 88 | return 3; 89 | else 90 | return 5; 91 | } 92 | return 0; 93 | } 94 | 95 | private int getNodeMod() 96 | { 97 | int roll = rand.nextInt(50); 98 | if (roll < 20) 99 | return 0; 100 | else if (roll < 40) 101 | return 1; 102 | else 103 | return 2; 104 | } 105 | 106 | private boolean checkItemEquals(ItemStack target, ItemStack input) 107 | { 108 | if (input == null && target != null || input != null && target == null) 109 | { 110 | return false; 111 | } 112 | return (target.getItem() == input.getItem() && 113 | (!target.hasTagCompound() || ItemStack.areItemStackTagsEqual(target, input)) && 114 | (target.getItemDamage() == OreDictionary.WILDCARD_VALUE|| target.getItemDamage() == input.getItemDamage())); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/wands/WandTriggerRegistry.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.wands; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | import net.minecraft.block.Block; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.world.World; 11 | 12 | /** 13 | * This class serves a similar function to IWandable in that it allows wands to interact 14 | * with object in the world. In this case it is most useful for adding interaction with non-mod 15 | * blocks where you can't control what happens in their code. 16 | * Example where it is used is in crafting the thaumonomicon from a bookshelf and the 17 | * crucible from a cauldron 18 | * 19 | * @author azanor 20 | * 21 | */ 22 | public class WandTriggerRegistry { 23 | 24 | private static HashMap> triggers = new HashMap>(); 25 | private static final String DEFAULT = "default"; 26 | 27 | /** 28 | * Registers an action to perform when a casting wand right clicks on a specific block. 29 | * A manager class needs to be created that implements IWandTriggerManager. 30 | * @param manager 31 | * @param event a logical number that you can use to differentiate different events or actions 32 | * @param block 33 | * @param meta send -1 as a wildcard value for all possible meta values 34 | * @param modid a unique identifier. It is best to register your own triggers using your mod id to avoid conflicts with mods that register triggers for the same block 35 | */ 36 | public static void registerWandBlockTrigger(IWandTriggerManager manager, int event, Block block, int meta, String modid) { 37 | if (!triggers.containsKey(modid)) { 38 | triggers.put(modid, new HashMap()); 39 | } 40 | HashMap temp = triggers.get(modid); 41 | temp.put(Arrays.asList(block,meta),Arrays.asList(manager,event)); 42 | triggers.put(modid, temp); 43 | } 44 | 45 | /** 46 | * for legacy support 47 | */ 48 | public static void registerWandBlockTrigger(IWandTriggerManager manager, int event, Block block, int meta) { 49 | registerWandBlockTrigger(manager, event, block, meta, DEFAULT); 50 | } 51 | 52 | /** 53 | * Checks all trigger registries if one exists for the given block and meta 54 | * @param block 55 | * @param meta 56 | * @return 57 | */ 58 | public static boolean hasTrigger(Block block, int meta) { 59 | for (String modid:triggers.keySet()) { 60 | HashMap temp = triggers.get(modid); 61 | if (temp.containsKey(Arrays.asList(block,meta)) || 62 | temp.containsKey(Arrays.asList(block,-1))) return true; 63 | } 64 | return false; 65 | } 66 | 67 | /** 68 | * modid sensitive version 69 | */ 70 | public static boolean hasTrigger(Block block, int meta, String modid) { 71 | if (!triggers.containsKey(modid)) return false; 72 | HashMap temp = triggers.get(modid); 73 | if (temp.containsKey(Arrays.asList(block,meta)) || 74 | temp.containsKey(Arrays.asList(block,-1))) return true; 75 | return false; 76 | } 77 | 78 | 79 | /** 80 | * This is called by the onItemUseFirst function in wands. 81 | * Parameters and return value functions like you would expect for that function. 82 | * @param world 83 | * @param wand 84 | * @param player 85 | * @param x 86 | * @param y 87 | * @param z 88 | * @param side 89 | * @param block 90 | * @param meta 91 | * @return 92 | */ 93 | public static boolean performTrigger(World world, ItemStack wand, EntityPlayer player, 94 | int x, int y, int z, int side, Block block, int meta) { 95 | 96 | for (String modid:triggers.keySet()) { 97 | HashMap temp = triggers.get(modid); 98 | List l = temp.get(Arrays.asList(block,meta)); 99 | if (l==null) l = temp.get(Arrays.asList(block,-1)); 100 | if (l==null) continue; 101 | 102 | IWandTriggerManager manager = (IWandTriggerManager) l.get(0); 103 | int event = (Integer) l.get(1); 104 | boolean result = manager.performTrigger(world, wand, player, x, y, z, side, event); 105 | if (result) return true; 106 | } 107 | return false; 108 | } 109 | 110 | /** 111 | * modid sensitive version 112 | */ 113 | public static boolean performTrigger(World world, ItemStack wand, EntityPlayer player, 114 | int x, int y, int z, int side, Block block, int meta, String modid) { 115 | if (!triggers.containsKey(modid)) return false; 116 | HashMap temp = triggers.get(modid); 117 | List l = temp.get(Arrays.asList(block,meta)); 118 | if (l==null) l = temp.get(Arrays.asList(block,-1)); 119 | if (l==null) return false; 120 | 121 | IWandTriggerManager manager = (IWandTriggerManager) l.get(0); 122 | int event = (Integer) l.get(1); 123 | return manager.performTrigger(world, wand, player, x, y, z, side, event); 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/visnet/TileVisNode.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.visnet; 2 | 3 | import java.lang.ref.WeakReference; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | 7 | import thaumcraft.api.TileThaumcraft; 8 | import thaumcraft.api.WorldCoordinates; 9 | import thaumcraft.api.aspects.Aspect; 10 | 11 | /** 12 | * @author Azanor 13 | * 14 | * The tile entity used by nodes in the vis energy network. A node is either a source (like an aura node), 15 | * a transport relay or vis receiver (like the infernal furnace). 16 | * 17 | */ 18 | public abstract class TileVisNode extends TileThaumcraft { 19 | 20 | WeakReference parent = null; 21 | ArrayList> children = new ArrayList>(); 22 | 23 | /** 24 | * @return the WorldCoordinates location of where this node is located 25 | */ 26 | public WorldCoordinates getLocation() { 27 | return new WorldCoordinates(this); 28 | } 29 | 30 | /** 31 | * @return the number of blocks away this node will check for parent nodes to connect to. 32 | */ 33 | public abstract int getRange(); 34 | 35 | /** 36 | * @return true if this is the source or root node of the vis network. 37 | */ 38 | public abstract boolean isSource(); 39 | 40 | /** 41 | * This method should never be called directly. Use VisNetHandler.drainVis() instead 42 | * @param aspect what aspect to drain 43 | * @param vis how much to drain 44 | * @return how much was actually drained 45 | */ 46 | public int consumeVis(Aspect aspect, int vis) { 47 | if (VisNetHandler.isNodeValid(getParent())) { 48 | int out = getParent().get().consumeVis(aspect, vis); 49 | if (out>0) { 50 | triggerConsumeEffect(aspect); 51 | } 52 | return out; 53 | } 54 | return 0; 55 | } 56 | 57 | public void removeThisNode() { 58 | for (WeakReference n:getChildren()) { 59 | if (n!=null && n.get()!=null) { 60 | n.get().removeThisNode(); 61 | } 62 | } 63 | 64 | children = new ArrayList>(); 65 | if (VisNetHandler.isNodeValid(this.getParent())) { 66 | this.getParent().get().nodeRefresh=true; 67 | } 68 | this.setParent(null); 69 | this.parentChanged(); 70 | 71 | if (this.isSource()) { 72 | HashMap> sourcelist = VisNetHandler.sources.get(worldObj.provider.dimensionId); 73 | if (sourcelist==null) { 74 | sourcelist = new HashMap>(); 75 | } 76 | sourcelist.remove(getLocation()); 77 | VisNetHandler.sources.put( worldObj.provider.dimensionId, sourcelist ); 78 | } 79 | 80 | worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); 81 | } 82 | 83 | 84 | 85 | @Override 86 | public void invalidate() { 87 | removeThisNode(); 88 | super.invalidate(); 89 | } 90 | 91 | public void triggerConsumeEffect(Aspect aspect) { } 92 | 93 | /** 94 | * @return 95 | */ 96 | public WeakReference getParent() { 97 | return parent; 98 | } 99 | 100 | /** 101 | * @return 102 | */ 103 | public WeakReference getRootSource() { 104 | return VisNetHandler.isNodeValid(getParent()) ? 105 | getParent().get().getRootSource() : this.isSource() ? 106 | new WeakReference(this) : null; 107 | } 108 | 109 | /** 110 | * @param parent 111 | */ 112 | public void setParent(WeakReference parent) { 113 | this.parent = parent; 114 | } 115 | 116 | /** 117 | * @return 118 | */ 119 | public ArrayList> getChildren() { 120 | return children; 121 | } 122 | 123 | @Override 124 | public boolean canUpdate() { 125 | return true; 126 | } 127 | 128 | protected int nodeCounter = 0; 129 | private boolean nodeRegged = false; 130 | public boolean nodeRefresh = false; 131 | 132 | @Override 133 | public void updateEntity() { 134 | 135 | if (!worldObj.isRemote && ((nodeCounter++) % 40==0 || nodeRefresh)) { 136 | //check for changes 137 | if (!nodeRefresh && children.size()>0) { 138 | for (WeakReference n:children) { 139 | if (n==null || n.get()==null) { 140 | nodeRefresh=true; 141 | break; 142 | } 143 | } 144 | } 145 | 146 | //refresh linked nodes 147 | if (nodeRefresh) { 148 | for (WeakReference n:children) { 149 | if (n.get()!=null) { 150 | n.get().nodeRefresh=true; 151 | } 152 | } 153 | children.clear(); 154 | parent=null; 155 | } 156 | 157 | //redo stuff 158 | if (isSource() && !nodeRegged) { 159 | VisNetHandler.addSource(getWorldObj(), this); 160 | nodeRegged = true; 161 | } else 162 | if (!isSource() && !VisNetHandler.isNodeValid(getParent())) { 163 | setParent(VisNetHandler.addNode(getWorldObj(), this)); 164 | nodeRefresh=true; 165 | } 166 | 167 | if (nodeRefresh) { 168 | worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); 169 | parentChanged(); 170 | } 171 | nodeRefresh=false; 172 | } 173 | 174 | } 175 | 176 | public void parentChanged() { } 177 | 178 | /** 179 | * @return the type of shard this is attuned to: 180 | * none -1, air 0, fire 1, water 2, earth 3, order 4, entropy 5 181 | * Should return -1 for most implementations 182 | */ 183 | public byte getAttunement() { 184 | return -1; 185 | } 186 | 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/ShapelessArcaneRecipe.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | import thaumcraft.api.aspects.AspectList; 7 | import net.minecraft.block.Block; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.inventory.IInventory; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.world.World; 13 | import net.minecraftforge.oredict.OreDictionary; 14 | import thaumcraft.api.ThaumcraftApiHelper; 15 | 16 | public class ShapelessArcaneRecipe implements IArcaneRecipe 17 | { 18 | private ItemStack output = null; 19 | private ArrayList input = new ArrayList(); 20 | 21 | public AspectList aspects = null; 22 | public String research; 23 | 24 | public ShapelessArcaneRecipe(String research, Block result, AspectList aspects, Object... recipe){ this(research,new ItemStack(result),aspects, recipe); } 25 | public ShapelessArcaneRecipe(String research, Item result, AspectList aspects, Object... recipe){ this(research,new ItemStack(result),aspects, recipe); } 26 | 27 | public ShapelessArcaneRecipe(String research, ItemStack result, AspectList aspects, Object... recipe) 28 | { 29 | output = result.copy(); 30 | this.research = research; 31 | this.aspects = aspects; 32 | for (Object in : recipe) 33 | { 34 | if (in instanceof ItemStack) 35 | { 36 | input.add(((ItemStack)in).copy()); 37 | } 38 | else if (in instanceof Item) 39 | { 40 | input.add(new ItemStack((Item)in)); 41 | } 42 | else if (in instanceof Block) 43 | { 44 | input.add(new ItemStack((Block)in)); 45 | } 46 | else if (in instanceof String) 47 | { 48 | input.add(OreDictionary.getOres((String)in)); 49 | } 50 | else 51 | { 52 | String ret = "Invalid shapeless ore recipe: "; 53 | for (Object tmp : recipe) 54 | { 55 | ret += tmp + ", "; 56 | } 57 | ret += output; 58 | throw new RuntimeException(ret); 59 | } 60 | } 61 | } 62 | 63 | @Override 64 | public int getRecipeSize(){ return input.size(); } 65 | 66 | @Override 67 | public ItemStack getRecipeOutput(){ return output; } 68 | 69 | @Override 70 | public ItemStack getCraftingResult(IInventory var1){ return output.copy(); } 71 | 72 | @Override 73 | public boolean matches(IInventory var1, World world, EntityPlayer player) 74 | { 75 | if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) { 76 | return false; 77 | } 78 | 79 | ArrayList required = new ArrayList(input); 80 | 81 | for (int x = 0; x < 9; x++) 82 | { 83 | ItemStack slot = var1.getStackInSlot(x); 84 | 85 | if (slot != null) 86 | { 87 | boolean inRecipe = false; 88 | Iterator req = required.iterator(); 89 | 90 | while (req.hasNext()) 91 | { 92 | boolean match = false; 93 | 94 | Object next = req.next(); 95 | 96 | if (next instanceof ItemStack) 97 | { 98 | match = checkItemEquals((ItemStack)next, slot); 99 | } 100 | else if (next instanceof ArrayList) 101 | { 102 | for (ItemStack item : (ArrayList)next) 103 | { 104 | match = match || checkItemEquals(item, slot); 105 | } 106 | } 107 | 108 | if (match) 109 | { 110 | inRecipe = true; 111 | required.remove(next); 112 | break; 113 | } 114 | } 115 | 116 | if (!inRecipe) 117 | { 118 | return false; 119 | } 120 | } 121 | } 122 | 123 | return required.isEmpty(); 124 | } 125 | 126 | private boolean checkItemEquals(ItemStack target, ItemStack input) 127 | { 128 | return (target.getItem() == input.getItem() && 129 | (!target.hasTagCompound() || ItemStack.areItemStackTagsEqual(target, input)) && 130 | (target.getItemDamage() == OreDictionary.WILDCARD_VALUE || target.getItemDamage() == input.getItemDamage())); 131 | } 132 | 133 | /** 134 | * Returns the input for this recipe, any mod accessing this value should never 135 | * manipulate the values in this array as it will effect the recipe itself. 136 | * @return The recipes input vales. 137 | */ 138 | public ArrayList getInput() 139 | { 140 | return this.input; 141 | } 142 | 143 | @Override 144 | public AspectList getAspects() { 145 | return aspects; 146 | } 147 | 148 | @Override 149 | public AspectList getAspects(IInventory inv) { 150 | return aspects; 151 | } 152 | 153 | @Override 154 | public String getResearch() { 155 | return research; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/crafting/InfusionEnchantmentRecipe.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.crafting; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.Map; 6 | 7 | import thaumcraft.api.aspects.AspectList; 8 | import net.minecraft.enchantment.Enchantment; 9 | import net.minecraft.enchantment.EnchantmentHelper; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.world.World; 13 | import net.minecraftforge.oredict.OreDictionary; 14 | import thaumcraft.api.ThaumcraftApiHelper; 15 | 16 | public class InfusionEnchantmentRecipe 17 | { 18 | 19 | public AspectList aspects; 20 | public String research; 21 | public ItemStack[] components; 22 | public Enchantment enchantment; 23 | public int recipeXP; 24 | public int instability; 25 | 26 | public InfusionEnchantmentRecipe(String research, Enchantment input, int inst, 27 | AspectList aspects2, ItemStack[] recipe) { 28 | this.research = research; 29 | this.enchantment = input; 30 | this.aspects = aspects2; 31 | this.components = recipe; 32 | this.instability = inst; 33 | this.recipeXP = Math.max(1, input.getMinEnchantability(1)/3); 34 | } 35 | 36 | /** 37 | * Used to check if a recipe matches current crafting inventory 38 | * @param player 39 | */ 40 | public boolean matches(ArrayList input, ItemStack central, World world, EntityPlayer player) { 41 | if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) { 42 | return false; 43 | } 44 | 45 | if (!enchantment.canApply(central) || !central.getItem().isItemTool(central)) { 46 | return false; 47 | } 48 | 49 | Map map1 = EnchantmentHelper.getEnchantments(central); 50 | Iterator iterator = map1.keySet().iterator(); 51 | while (iterator.hasNext()) 52 | { 53 | int j1 = ((Integer)iterator.next()).intValue(); 54 | Enchantment ench = Enchantment.enchantmentsList[j1]; 55 | if (j1 == enchantment.effectId && 56 | EnchantmentHelper.getEnchantmentLevel(j1, central)>=ench.getMaxLevel()) 57 | return false; 58 | if (enchantment.effectId != ench.effectId && 59 | (!enchantment.canApplyTogether(ench) || 60 | !ench.canApplyTogether(enchantment))) { 61 | return false; 62 | } 63 | } 64 | 65 | ItemStack i2 = null; 66 | 67 | ArrayList ii = new ArrayList(); 68 | for (ItemStack is:input) { 69 | ii.add(is.copy()); 70 | } 71 | 72 | for (ItemStack comp:components) { 73 | boolean b=false; 74 | for (int a=0;a stack0.getMaxStackSize() ? false : t1)); 109 | } 110 | 111 | 112 | public Enchantment getEnchantment() { 113 | return enchantment; 114 | 115 | } 116 | 117 | public AspectList getAspects() { 118 | return aspects; 119 | 120 | } 121 | 122 | public String getResearch() { 123 | return research; 124 | 125 | } 126 | 127 | public int calcInstability(ItemStack recipeInput) { 128 | int i = 0; 129 | Map map1 = EnchantmentHelper.getEnchantments(recipeInput); 130 | Iterator iterator = map1.keySet().iterator(); 131 | while (iterator.hasNext()) 132 | { 133 | int j1 = ((Integer)iterator.next()).intValue(); 134 | i += EnchantmentHelper.getEnchantmentLevel(j1, recipeInput); 135 | } 136 | return (i/2) + instability; 137 | } 138 | 139 | public int calcXP(ItemStack recipeInput) { 140 | return recipeXP * (1+EnchantmentHelper.getEnchantmentLevel(enchantment.effectId, recipeInput)); 141 | } 142 | 143 | public float getEssentiaMod(ItemStack recipeInput) { 144 | float mod = EnchantmentHelper.getEnchantmentLevel(enchantment.effectId, recipeInput); 145 | Map map1 = EnchantmentHelper.getEnchantments(recipeInput); 146 | Iterator iterator = map1.keySet().iterator(); 147 | while (iterator.hasNext()) 148 | { 149 | int j1 = ((Integer)iterator.next()).intValue(); 150 | if (j1 != enchantment.effectId) 151 | mod += EnchantmentHelper.getEnchantmentLevel(j1, recipeInput) * .1f; 152 | } 153 | return mod; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/recipe/RecipeAttune.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.recipe; 2 | 3 | import gnu.trove.map.TMap; 4 | import gnu.trove.map.hash.THashMap; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.inventory.IInventory; 7 | import net.minecraft.inventory.InventoryCrafting; 8 | import net.minecraft.item.ItemStack; 9 | import net.minecraft.item.crafting.IRecipe; 10 | import net.minecraft.nbt.NBTTagCompound; 11 | import net.minecraft.world.World; 12 | import net.minecraftforge.oredict.OreDictionary; 13 | import shukaro.nodalmechanics.NodalMechanics; 14 | import shukaro.nodalmechanics.items.NodalItems; 15 | import thaumcraft.api.ItemApi; 16 | import thaumcraft.api.ThaumcraftApi; 17 | import thaumcraft.api.ThaumcraftApiHelper; 18 | import thaumcraft.api.aspects.Aspect; 19 | import thaumcraft.api.aspects.AspectList; 20 | import thaumcraft.api.crafting.IArcaneRecipe; 21 | 22 | public class RecipeAttune implements IArcaneRecipe 23 | { 24 | private ItemStack output; 25 | 26 | @Override 27 | public boolean matches(IInventory inventory, World world, EntityPlayer player) 28 | { 29 | if (!ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), getResearch())) 30 | return false; 31 | ItemStack matrix = null; 32 | for (int i=0; i<3; i++) 33 | { 34 | for (int j=0; j<3; j++) 35 | { 36 | ItemStack slotStack = ThaumcraftApiHelper.getStackInRowAndColumn(inventory, i, j); 37 | if (matrix != null && checkItemEquals(slotStack, new ItemStack(NodalItems.itemMatrix))) 38 | return false; 39 | else if (checkItemEquals(slotStack, new ItemStack(NodalItems.itemMatrix))) 40 | matrix = slotStack; 41 | } 42 | } 43 | if (matrix == null) 44 | return false; 45 | TMap aspectMap = new THashMap(); 46 | for (int i=0; i<3; i++) 47 | { 48 | for (int j=0; j<3; j++) 49 | { 50 | ItemStack slotStack = ThaumcraftApiHelper.getStackInRowAndColumn(inventory, i, j); 51 | if (slotStack == null) 52 | continue; 53 | else if (slotStack.getItem().equals(NodalItems.itemMatrix)) 54 | continue; 55 | else if (slotStack.getItem().equals(ItemApi.getItem("itemEssence", 1).getItem())) 56 | { 57 | if (!slotStack.hasTagCompound()) 58 | return false; 59 | else 60 | { 61 | AspectList list = new AspectList(); 62 | list.readFromNBT(slotStack.getTagCompound()); 63 | if (list.size() > 0) 64 | { 65 | for (Aspect aspect : list.getAspects()) 66 | { 67 | if (aspectMap.containsKey(aspect.getTag())) 68 | aspectMap.put(aspect.getTag(), aspectMap.get(aspect.getTag()) + 1); 69 | else 70 | aspectMap.put(aspect.getTag(), 1); 71 | } 72 | } 73 | else 74 | return false; 75 | } 76 | } 77 | else 78 | return false; 79 | } 80 | } 81 | if (aspectMap.size() > 0) 82 | { 83 | String aspects = ""; 84 | for (String aspect : aspectMap.keySet()) 85 | { 86 | for (int i=0; i \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/research/ResearchPage.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.research; 2 | 3 | import java.util.List; 4 | 5 | import thaumcraft.api.aspects.AspectList; 6 | import thaumcraft.api.crafting.InfusionEnchantmentRecipe; 7 | import thaumcraft.api.crafting.InfusionRecipe; 8 | import net.minecraft.item.ItemStack; 9 | import net.minecraft.item.crafting.FurnaceRecipes; 10 | import net.minecraft.item.crafting.IRecipe; 11 | import net.minecraft.util.ResourceLocation; 12 | import net.minecraft.util.StatCollector; 13 | import thaumcraft.api.crafting.CrucibleRecipe; 14 | import thaumcraft.api.crafting.IArcaneRecipe; 15 | 16 | public class ResearchPage { 17 | public static enum PageType 18 | { 19 | TEXT, 20 | TEXT_CONCEALED, 21 | IMAGE, 22 | CRUCIBLE_CRAFTING, 23 | ARCANE_CRAFTING, 24 | ASPECTS, 25 | NORMAL_CRAFTING, 26 | INFUSION_CRAFTING, 27 | COMPOUND_CRAFTING, 28 | INFUSION_ENCHANTMENT, 29 | SMELTING 30 | } 31 | 32 | public PageType type = PageType.TEXT; 33 | 34 | public String text=null; 35 | public String research=null; 36 | public ResourceLocation image=null; 37 | public AspectList aspects=null; 38 | public Object recipe=null; 39 | public ItemStack recipeOutput=null; 40 | 41 | /** 42 | * @param text this can (but does not have to) be a reference to a localization variable, not the actual text. 43 | */ 44 | public ResearchPage(String text) { 45 | this.type = PageType.TEXT; 46 | this.text = text; 47 | } 48 | 49 | /** 50 | * @param research this page will only be displayed if the player has discovered this research 51 | * @param text this can (but does not have to) be a reference to a localization variable, not the actual text. 52 | */ 53 | public ResearchPage(String research, String text) { 54 | this.type = PageType.TEXT_CONCEALED; 55 | this.research = research; 56 | this.text = text; 57 | } 58 | 59 | /** 60 | * @param recipe a vanilla crafting recipe. 61 | */ 62 | public ResearchPage(IRecipe recipe) { 63 | this.type = PageType.NORMAL_CRAFTING; 64 | this.recipe = recipe; 65 | this.recipeOutput = recipe.getRecipeOutput(); 66 | } 67 | 68 | /** 69 | * @param recipe a collection of vanilla crafting recipes. 70 | */ 71 | public ResearchPage(IRecipe[] recipe) { 72 | this.type = PageType.NORMAL_CRAFTING; 73 | this.recipe = recipe; 74 | } 75 | 76 | /** 77 | * @param recipe a collection of arcane crafting recipes. 78 | */ 79 | public ResearchPage(IArcaneRecipe[] recipe) { 80 | this.type = PageType.ARCANE_CRAFTING; 81 | this.recipe = recipe; 82 | } 83 | 84 | /** 85 | * @param recipe a collection of arcane crafting recipes. 86 | */ 87 | public ResearchPage(CrucibleRecipe[] recipe) { 88 | this.type = PageType.CRUCIBLE_CRAFTING; 89 | this.recipe = recipe; 90 | } 91 | 92 | /** 93 | * @param recipe a collection of infusion crafting recipes. 94 | */ 95 | public ResearchPage(InfusionRecipe[] recipe) { 96 | this.type = PageType.INFUSION_CRAFTING; 97 | this.recipe = recipe; 98 | } 99 | 100 | /** 101 | * @param recipe a compound crafting recipe. 102 | */ 103 | public ResearchPage(List recipe) { 104 | this.type = PageType.COMPOUND_CRAFTING; 105 | this.recipe = recipe; 106 | } 107 | 108 | /** 109 | * @param recipe an arcane worktable crafting recipe. 110 | */ 111 | public ResearchPage(IArcaneRecipe recipe) { 112 | this.type = PageType.ARCANE_CRAFTING; 113 | this.recipe = recipe; 114 | this.recipeOutput = recipe.getRecipeOutput(); 115 | } 116 | 117 | /** 118 | * @param recipe an alchemy crafting recipe. 119 | */ 120 | public ResearchPage(CrucibleRecipe recipe) { 121 | this.type = PageType.CRUCIBLE_CRAFTING; 122 | this.recipe = recipe; 123 | this.recipeOutput = recipe.getRecipeOutput(); 124 | } 125 | 126 | /** 127 | * @param recipe a furnace smelting crafting recipe. 128 | */ 129 | public ResearchPage(ItemStack input) { 130 | this.type = PageType.SMELTING; 131 | this.recipe = input; 132 | this.recipeOutput = FurnaceRecipes.smelting().getSmeltingResult(input); 133 | } 134 | 135 | /** 136 | * @param recipe an infusion crafting recipe. 137 | */ 138 | public ResearchPage(InfusionRecipe recipe) { 139 | this.type = PageType.INFUSION_CRAFTING; 140 | this.recipe = recipe; 141 | if (recipe.getRecipeOutput() instanceof ItemStack) { 142 | this.recipeOutput = (ItemStack) recipe.getRecipeOutput(); 143 | } else { 144 | this.recipeOutput = recipe.getRecipeInput(); 145 | } 146 | } 147 | 148 | /** 149 | * @param recipe an infusion crafting recipe. 150 | */ 151 | public ResearchPage(InfusionEnchantmentRecipe recipe) { 152 | this.type = PageType.INFUSION_ENCHANTMENT; 153 | this.recipe = recipe; 154 | // if (recipe.recipeOutput instanceof ItemStack) { 155 | // this.recipeOutput = (ItemStack) recipe.recipeOutput; 156 | // } else { 157 | // this.recipeOutput = recipe.recipeInput; 158 | // } 159 | } 160 | 161 | /** 162 | * @param image 163 | * @param caption this can (but does not have to) be a reference to a localization variable, not the actual text. 164 | */ 165 | public ResearchPage(ResourceLocation image, String caption) { 166 | this.type = PageType.IMAGE; 167 | this.image = image; 168 | this.text = caption; 169 | } 170 | 171 | /** 172 | * This function should really not be called directly - used internally 173 | */ 174 | public ResearchPage(AspectList as) { 175 | this.type = PageType.ASPECTS; 176 | this.aspects = as; 177 | } 178 | 179 | /** 180 | * returns a localized text of the text field (if one exists). Returns the text field itself otherwise. 181 | * @return 182 | */ 183 | public String getTranslatedText() { 184 | String ret=""; 185 | if (text != null) { 186 | ret = StatCollector.translateToLocal(text); 187 | if (ret.isEmpty()) ret = text; 188 | } 189 | return ret; 190 | } 191 | 192 | 193 | } 194 | -------------------------------------------------------------------------------- /src/main/java/shukaro/nodalmechanics/recipe/NodalRecipes.java: -------------------------------------------------------------------------------- 1 | package shukaro.nodalmechanics.recipe; 2 | 3 | import net.minecraft.item.ItemStack; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import shukaro.nodalmechanics.items.NodalItems; 6 | import thaumcraft.api.ItemApi; 7 | import thaumcraft.api.ThaumcraftApi; 8 | import thaumcraft.api.aspects.Aspect; 9 | import thaumcraft.api.aspects.AspectList; 10 | import thaumcraft.api.crafting.InfusionRecipe; 11 | import thaumcraft.api.crafting.ShapedArcaneRecipe; 12 | 13 | public class NodalRecipes 14 | { 15 | public static ShapedArcaneRecipe matrixRecipe; 16 | public static ShapedArcaneRecipe variedAttuneRecipe; 17 | public static ShapedArcaneRecipe sameAttuneRecipe; 18 | public static InfusionRecipe variedNodeRecipe; 19 | public static InfusionRecipe sameNodeRecipe; 20 | 21 | public NodalRecipes() 22 | { 23 | matrixRecipe = new ShapedArcaneRecipe("NODECATALYZATION", new ItemStack(NodalItems.itemMatrix), new AspectList().add(Aspect.ORDER, 20).add(Aspect.ENTROPY, 20), new Object[] { 24 | "XYX", 25 | "YZY", 26 | "XYX", 27 | Character.valueOf('X'), ItemApi.getItem("itemResource", 14), 28 | Character.valueOf('Y'), ItemApi.getBlock("blockMagicalLog", 0), 29 | Character.valueOf('Z'), ItemApi.getBlock("blockJar", 0) 30 | }); 31 | 32 | NBTTagCompound variedAttuneTag = new NBTTagCompound(); 33 | variedAttuneTag.setString("aspects", "aer,terra,ignis,aqua,ordo,perditio"); 34 | ItemStack variedAttune = new ItemStack(NodalItems.itemMatrix); 35 | variedAttune.setTagCompound(variedAttuneTag); 36 | ItemStack[] phials = new ItemStack[6]; 37 | Aspect[] primals = new Aspect[] { Aspect.AIR, Aspect.EARTH, Aspect.FIRE, Aspect.WATER, Aspect.ORDER, Aspect.ENTROPY }; 38 | for (int i=0; i aspects = new LinkedHashMap();//aspects associated with this object 14 | 15 | 16 | /** 17 | * this creates a new aspect list with preloaded values based off the aspects of the given item. 18 | * @param the itemstack of the given item 19 | */ 20 | public AspectList(ItemStack stack) { 21 | try { 22 | AspectList temp = ThaumcraftApiHelper.getObjectAspects(stack); 23 | if (temp!=null) 24 | for (Aspect tag:temp.getAspects()) { 25 | add(tag,temp.getAmount(tag)); 26 | } 27 | } catch (Exception e) {} 28 | } 29 | 30 | public AspectList() { 31 | } 32 | 33 | public AspectList copy() { 34 | AspectList out = new AspectList(); 35 | for (Aspect a:this.getAspects()) 36 | out.add(a, this.getAmount(a)); 37 | return out; 38 | } 39 | 40 | /** 41 | * @return the amount of different aspects in this collection 42 | */ 43 | public int size() { 44 | return aspects.size(); 45 | } 46 | 47 | /** 48 | * @return the amount of total vis in this collection 49 | */ 50 | public int visSize() { 51 | int q = 0; 52 | 53 | for (Aspect as:aspects.keySet()) { 54 | q+=this.getAmount(as); 55 | } 56 | 57 | return q; 58 | } 59 | 60 | /** 61 | * @return an array of all the aspects in this collection 62 | */ 63 | public Aspect[] getAspects() { 64 | Aspect[] q = new Aspect[1]; 65 | return aspects.keySet().toArray(q); 66 | } 67 | 68 | /** 69 | * @return an array of all the aspects in this collection 70 | */ 71 | public Aspect[] getPrimalAspects() { 72 | AspectList t = new AspectList(); 73 | for (Aspect as:aspects.keySet()) { 74 | if (as.isPrimal()) { 75 | t.add(as,1); 76 | } 77 | } 78 | Aspect[] q = new Aspect[1]; 79 | return t.aspects.keySet().toArray(q); 80 | } 81 | 82 | /** 83 | * @return an array of all the aspects in this collection sorted by name 84 | */ 85 | public Aspect[] getAspectsSorted() { 86 | try { 87 | Aspect[] out = aspects.keySet().toArray(new Aspect[1]); 88 | boolean change=false; 89 | do { 90 | change=false; 91 | for(int a=0;a0) { 95 | out[a] = e2; 96 | out[a+1] = e1; 97 | change = true; 98 | break; 99 | } 100 | } 101 | } while (change==true); 102 | return out; 103 | } catch (Exception e) { 104 | return this.getAspects(); 105 | } 106 | } 107 | 108 | /** 109 | * @return an array of all the aspects in this collection sorted by amount 110 | */ 111 | public Aspect[] getAspectsSortedAmount() { 112 | try { 113 | Aspect[] out = aspects.keySet().toArray(new Aspect[1]); 114 | boolean change=false; 115 | do { 116 | change=false; 117 | for(int a=0;a0 && e2>0 && e2>e1) { 121 | Aspect ea = out[a]; 122 | Aspect eb = out[a+1]; 123 | out[a] = eb; 124 | out[a+1] = ea; 125 | change = true; 126 | break; 127 | } 128 | } 129 | } while (change==true); 130 | return out; 131 | } catch (Exception e) { 132 | return this.getAspects(); 133 | } 134 | } 135 | 136 | /** 137 | * @param key 138 | * @return the amount associated with the given aspect in this collection 139 | */ 140 | public int getAmount(Aspect key) { 141 | return aspects.get(key)==null?0:aspects.get(key); 142 | } 143 | 144 | /** 145 | * Reduces the amount of an aspect in this collection by the given amount. 146 | * @param key 147 | * @param amount 148 | * @return 149 | */ 150 | public boolean reduce(Aspect key, int amount) { 151 | if (getAmount(key)>=amount) { 152 | int am = getAmount(key)-amount; 153 | aspects.put(key, am); 154 | return true; 155 | } 156 | return false; 157 | } 158 | 159 | /** 160 | * Reduces the amount of an aspect in this collection by the given amount. 161 | * If reduced to 0 or less the aspect will be removed completely. 162 | * @param key 163 | * @param amount 164 | * @return 165 | */ 166 | public AspectList remove(Aspect key, int amount) { 167 | int am = getAmount(key)-amount; 168 | if (am<=0) aspects.remove(key); else 169 | this.aspects.put(key, am); 170 | return this; 171 | } 172 | 173 | /** 174 | * Simply removes the aspect from the list 175 | * @param key 176 | * @param amount 177 | * @return 178 | */ 179 | public AspectList remove(Aspect key) { 180 | aspects.remove(key); 181 | return this; 182 | } 183 | 184 | /** 185 | * Adds this aspect and amount to the collection. 186 | * If the aspect exists then its value will be increased by the given amount. 187 | * @param aspect 188 | * @param amount 189 | * @return 190 | */ 191 | public AspectList add(Aspect aspect, int amount) { 192 | if (this.aspects.containsKey(aspect)) { 193 | int oldamount = this.aspects.get(aspect); 194 | amount+=oldamount; 195 | } 196 | this.aspects.put( aspect, amount ); 197 | return this; 198 | } 199 | 200 | 201 | /** 202 | * Adds this aspect and amount to the collection. 203 | * If the aspect exists then only the highest of the old or new amount will be used. 204 | * @param aspect 205 | * @param amount 206 | * @return 207 | */ 208 | public AspectList merge(Aspect aspect, int amount) { 209 | if (this.aspects.containsKey(aspect)) { 210 | int oldamount = this.aspects.get(aspect); 211 | if (amount itemMap = new HashMap(); 89 | 90 | for (; idx < recipe.length; idx += 2) 91 | { 92 | Character chr = (Character)recipe[idx]; 93 | Object in = recipe[idx + 1]; 94 | 95 | if (in instanceof ItemStack) 96 | { 97 | itemMap.put(chr, ((ItemStack)in).copy()); 98 | } 99 | else if (in instanceof Item) 100 | { 101 | itemMap.put(chr, new ItemStack((Item)in)); 102 | } 103 | else if (in instanceof Block) 104 | { 105 | itemMap.put(chr, new ItemStack((Block)in, 1, OreDictionary.WILDCARD_VALUE)); 106 | } 107 | else if (in instanceof String) 108 | { 109 | itemMap.put(chr, OreDictionary.getOres((String)in)); 110 | } 111 | else 112 | { 113 | String ret = "Invalid shaped ore recipe: "; 114 | for (Object tmp : recipe) 115 | { 116 | ret += tmp + ", "; 117 | } 118 | ret += output; 119 | throw new RuntimeException(ret); 120 | } 121 | } 122 | 123 | input = new Object[width * height]; 124 | int x = 0; 125 | for (char chr : shape.toCharArray()) 126 | { 127 | input[x++] = itemMap.get(chr); 128 | } 129 | } 130 | 131 | @Override 132 | public ItemStack getCraftingResult(IInventory var1){ return output.copy(); } 133 | 134 | @Override 135 | public int getRecipeSize(){ return input.length; } 136 | 137 | @Override 138 | public ItemStack getRecipeOutput(){ return output; } 139 | 140 | @Override 141 | public boolean matches(IInventory inv, World world, EntityPlayer player) 142 | { 143 | if (research.length()>0 && !ThaumcraftApiHelper.isResearchComplete(player.getCommandSenderName(), research)) { 144 | return false; 145 | } 146 | for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++) 147 | { 148 | for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y) 149 | { 150 | if (checkMatch(inv, x, y, false)) 151 | { 152 | return true; 153 | } 154 | 155 | if (mirrored && checkMatch(inv, x, y, true)) 156 | { 157 | return true; 158 | } 159 | } 160 | } 161 | 162 | return false; 163 | } 164 | 165 | private boolean checkMatch(IInventory inv, int startX, int startY, boolean mirror) 166 | { 167 | for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++) 168 | { 169 | for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++) 170 | { 171 | int subX = x - startX; 172 | int subY = y - startY; 173 | Object target = null; 174 | 175 | if (subX >= 0 && subY >= 0 && subX < width && subY < height) 176 | { 177 | if (mirror) 178 | { 179 | target = input[width - subX - 1 + subY * width]; 180 | } 181 | else 182 | { 183 | target = input[subX + subY * width]; 184 | } 185 | } 186 | 187 | ItemStack slot = ThaumcraftApiHelper.getStackInRowAndColumn(inv, x, y); 188 | 189 | if (target instanceof ItemStack) 190 | { 191 | if (!checkItemEquals((ItemStack)target, slot)) 192 | { 193 | return false; 194 | } 195 | } 196 | else if (target instanceof ArrayList) 197 | { 198 | boolean matched = false; 199 | 200 | for (ItemStack item : (ArrayList)target) 201 | { 202 | matched = matched || checkItemEquals(item, slot); 203 | } 204 | 205 | if (!matched) 206 | { 207 | return false; 208 | } 209 | } 210 | else if (target == null && slot != null) 211 | { 212 | return false; 213 | } 214 | } 215 | } 216 | 217 | return true; 218 | } 219 | 220 | private boolean checkItemEquals(ItemStack target, ItemStack input) 221 | { 222 | if (input == null && target != null || input != null && target == null) 223 | { 224 | return false; 225 | } 226 | return (target.getItem() == input.getItem() && 227 | (!target.hasTagCompound() || ItemStack.areItemStackTagsEqual(target, input)) && 228 | (target.getItemDamage() == OreDictionary.WILDCARD_VALUE|| target.getItemDamage() == input.getItemDamage())); 229 | } 230 | 231 | public ShapedArcaneRecipe setMirrored(boolean mirror) 232 | { 233 | mirrored = mirror; 234 | return this; 235 | } 236 | 237 | /** 238 | * Returns the input for this recipe, any mod accessing this value should never 239 | * manipulate the values in this array as it will effect the recipe itself. 240 | * @return The recipes input vales. 241 | */ 242 | public Object[] getInput() 243 | { 244 | return this.input; 245 | } 246 | 247 | @Override 248 | public AspectList getAspects() { 249 | return aspects; 250 | } 251 | 252 | @Override 253 | public AspectList getAspects(IInventory inv) { 254 | return aspects; 255 | } 256 | 257 | @Override 258 | public String getResearch() { 259 | return research; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/aspects/Aspect.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.aspects; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.LinkedHashMap; 6 | 7 | import net.minecraft.util.ResourceLocation; 8 | import net.minecraft.util.StatCollector; 9 | 10 | import org.apache.commons.lang3.text.WordUtils; 11 | 12 | public class Aspect { 13 | 14 | String tag; 15 | Aspect[] components; 16 | int color; 17 | private String chatcolor; 18 | ResourceLocation image; 19 | int blend; 20 | 21 | /** 22 | * Use this constructor to register your own aspects. 23 | * @param tag the key that will be used to reference this aspect, as well as its latin display name 24 | * @param color color to display the tag in 25 | * @param components the aspects this one is formed from 26 | * @param image ResourceLocation pointing to a 32x32 icon of the aspect 27 | * @param blend GL11 blendmode (1 or 771). Used for rendering nodes. Default is 1 28 | */ 29 | public Aspect(String tag, int color, Aspect[] components, ResourceLocation image, int blend) { 30 | if (aspects.containsKey(tag)) throw new IllegalArgumentException(tag+" already registered!"); 31 | this.tag = tag; 32 | this.components = components; 33 | this.color = color; 34 | this.image = image; 35 | this.blend = blend; 36 | aspects.put(tag, this); 37 | } 38 | 39 | /** 40 | * Shortcut constructor I use for the default aspects - you shouldn't be using this. 41 | */ 42 | public Aspect(String tag, int color, Aspect[] components) { 43 | this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),1); 44 | } 45 | 46 | /** 47 | * Shortcut constructor I use for the default aspects - you shouldn't be using this. 48 | */ 49 | public Aspect(String tag, int color, Aspect[] components, int blend) { 50 | this(tag,color,components,new ResourceLocation("thaumcraft","textures/aspects/"+tag.toLowerCase()+".png"),blend); 51 | } 52 | 53 | /** 54 | * Shortcut constructor I use for the primal aspects - 55 | * you shouldn't use this as making your own primal aspects will break all the things. 56 | */ 57 | public Aspect(String tag, int color, String chatcolor, int blend) { 58 | this(tag,color,(Aspect[])null, blend); 59 | this.setChatcolor(chatcolor); 60 | } 61 | 62 | public int getColor() { 63 | return color; 64 | } 65 | 66 | public String getName() { 67 | return WordUtils.capitalizeFully(tag); 68 | } 69 | 70 | public String getLocalizedDescription() { 71 | return StatCollector.translateToLocal("tc.aspect."+tag); 72 | } 73 | 74 | public String getTag() { 75 | return tag; 76 | } 77 | 78 | public void setTag(String tag) { 79 | this.tag = tag; 80 | } 81 | 82 | public Aspect[] getComponents() { 83 | return components; 84 | } 85 | 86 | public void setComponents(Aspect[] components) { 87 | this.components = components; 88 | } 89 | 90 | public ResourceLocation getImage() { 91 | return image; 92 | } 93 | 94 | public static Aspect getAspect(String tag) { 95 | return aspects.get(tag); 96 | } 97 | 98 | public int getBlend() { 99 | return blend; 100 | } 101 | 102 | public void setBlend(int blend) { 103 | this.blend = blend; 104 | } 105 | 106 | public boolean isPrimal() { 107 | return getComponents()==null || getComponents().length!=2; 108 | } 109 | 110 | /////////////////////////////// 111 | public static ArrayList getPrimalAspects() { 112 | ArrayList primals = new ArrayList(); 113 | Collection pa = aspects.values(); 114 | for (Aspect aspect:pa) { 115 | if (aspect.isPrimal()) primals.add(aspect); 116 | } 117 | return primals; 118 | } 119 | 120 | public static ArrayList getCompoundAspects() { 121 | ArrayList compounds = new ArrayList(); 122 | Collection pa = aspects.values(); 123 | for (Aspect aspect:pa) { 124 | if (!aspect.isPrimal()) compounds.add(aspect); 125 | } 126 | return compounds; 127 | } 128 | 129 | public String getChatcolor() { 130 | return chatcolor; 131 | } 132 | 133 | public void setChatcolor(String chatcolor) { 134 | this.chatcolor = chatcolor; 135 | } 136 | 137 | 138 | /////////////////////////////// 139 | public static LinkedHashMap aspects = new LinkedHashMap(); 140 | 141 | //PRIMAL 142 | public static final Aspect AIR = new Aspect("aer",0xffff7e,"e",1); 143 | public static final Aspect EARTH = new Aspect("terra",0x56c000,"2",1); 144 | public static final Aspect FIRE = new Aspect("ignis",0xff5a01,"c",1); 145 | public static final Aspect WATER = new Aspect("aqua",0x3cd4fc,"3",1); 146 | public static final Aspect ORDER = new Aspect("ordo",0xd5d4ec,"7",1); 147 | public static final Aspect ENTROPY = new Aspect("perditio",0x404040,"8",771); 148 | 149 | //SECONDARY 150 | public static final Aspect VOID = new Aspect("vacuos",0x888888, new Aspect[] {AIR, ENTROPY},771); 151 | public static final Aspect LIGHT = new Aspect("lux",0xfff663, new Aspect[] {AIR, FIRE}); 152 | public static final Aspect WEATHER = new Aspect("tempestas",0xFFFFFF, new Aspect[] {AIR, WATER}); 153 | public static final Aspect MOTION = new Aspect("motus",0xcdccf4, new Aspect[] {AIR, ORDER}); 154 | public static final Aspect COLD = new Aspect("gelum",0xe1ffff, new Aspect[] {FIRE, ENTROPY}); 155 | public static final Aspect CRYSTAL = new Aspect("vitreus",0x80ffff, new Aspect[] {EARTH, ORDER}); 156 | public static final Aspect LIFE = new Aspect("victus",0xde0005, new Aspect[] {WATER, EARTH}); 157 | public static final Aspect POISON = new Aspect("venenum",0x89f000, new Aspect[] {WATER, ENTROPY}); 158 | public static final Aspect ENERGY = new Aspect("potentia",0xc0ffff, new Aspect[] {ORDER, FIRE}); 159 | public static final Aspect EXCHANGE = new Aspect("permutatio",0x578357, new Aspect[] {ENTROPY, ORDER}); 160 | // public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {AIR, EARTH}); 161 | // public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {FIRE, EARTH}); 162 | // public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {FIRE, WATER}); 163 | // public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {ORDER, WATER}); 164 | // public static final Aspect ?? = new Aspect("??",0xcdccf4, new Aspect[] {EARTH, ENTROPY}); 165 | 166 | //TERTIARY 167 | public static final Aspect METAL = new Aspect("metallum",0xb5b5cd, new Aspect[] {EARTH, CRYSTAL}); 168 | public static final Aspect DEATH = new Aspect("mortuus",0x887788, new Aspect[] {LIFE, ENTROPY}); 169 | public static final Aspect FLIGHT = new Aspect("volatus",0xe7e7d7, new Aspect[] {AIR, MOTION}); 170 | public static final Aspect DARKNESS = new Aspect("tenebrae",0x222222, new Aspect[] {VOID, LIGHT}); 171 | public static final Aspect SOUL = new Aspect("spiritus",0xebebfb, new Aspect[] {LIFE, DEATH}); 172 | public static final Aspect HEAL = new Aspect("sano",0xff2f34, new Aspect[] {LIFE, ORDER}); 173 | public static final Aspect TRAVEL = new Aspect("iter",0xe0585b, new Aspect[] {MOTION, EARTH}); 174 | public static final Aspect ELDRITCH = new Aspect("alienis",0x805080, new Aspect[] {VOID, DARKNESS}); 175 | public static final Aspect MAGIC = new Aspect("praecantatio",0x9700c0, new Aspect[] {VOID, ENERGY}); 176 | public static final Aspect AURA = new Aspect("auram",0xffc0ff, new Aspect[] {MAGIC, AIR}); 177 | public static final Aspect TAINT = new Aspect("vitium",0x800080, new Aspect[] {MAGIC, ENTROPY}); 178 | public static final Aspect SLIME = new Aspect("limus",0x01f800, new Aspect[] {LIFE, WATER}); 179 | public static final Aspect PLANT = new Aspect("herba",0x01ac00, new Aspect[] {LIFE, EARTH}); 180 | public static final Aspect TREE = new Aspect("arbor",0x876531, new Aspect[] {AIR, PLANT}); 181 | public static final Aspect BEAST = new Aspect("bestia",0x9f6409, new Aspect[] {MOTION, LIFE}); 182 | public static final Aspect FLESH = new Aspect("corpus",0xee478d, new Aspect[] {DEATH, BEAST}); 183 | public static final Aspect UNDEAD = new Aspect("exanimis",0x3a4000, new Aspect[] {MOTION, DEATH}); 184 | public static final Aspect MIND = new Aspect("cognitio",0xffc2b3, new Aspect[] {EARTH, SOUL}); 185 | public static final Aspect SENSES = new Aspect("sensus",0x0fd9ff, new Aspect[] {AIR, SOUL}); 186 | public static final Aspect MAN = new Aspect("humanus",0xffd7c0, new Aspect[] {BEAST, MIND}); 187 | public static final Aspect CROP = new Aspect("messis",0xe1b371, new Aspect[] {PLANT, MAN}); 188 | public static final Aspect MINE = new Aspect("perfodio",0xdcd2d8, new Aspect[] {MAN, EARTH}); 189 | public static final Aspect TOOL = new Aspect("instrumentum",0x4040ee, new Aspect[] {MAN, ORDER}); 190 | public static final Aspect HARVEST = new Aspect("meto",0xeead82, new Aspect[] {CROP, TOOL}); 191 | public static final Aspect WEAPON = new Aspect("telum",0xc05050, new Aspect[] {TOOL, ENTROPY}); 192 | public static final Aspect ARMOR = new Aspect("tutamen",0x00c0c0, new Aspect[] {TOOL, EARTH}); 193 | public static final Aspect HUNGER = new Aspect("fames",0x9a0305, new Aspect[] {LIFE, VOID}); 194 | public static final Aspect GREED = new Aspect("lucrum",0xe6be44, new Aspect[] {MAN, HUNGER}); 195 | public static final Aspect CRAFT = new Aspect("fabrico",0x809d80, new Aspect[] {MAN, TOOL}); 196 | public static final Aspect CLOTH = new Aspect("pannus",0xeaeac2, new Aspect[] {TOOL, BEAST}); 197 | public static final Aspect MECHANISM = new Aspect("machina",0x8080a0, new Aspect[] {MOTION, TOOL}); 198 | public static final Aspect TRAP = new Aspect("vinculum",0x9a8080, new Aspect[] {MOTION, ENTROPY}); 199 | 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/api/java/thaumcraft/api/visnet/VisNetHandler.java: -------------------------------------------------------------------------------- 1 | package thaumcraft.api.visnet; 2 | 3 | import java.lang.ref.WeakReference; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | 8 | import thaumcraft.api.WorldCoordinates; 9 | import thaumcraft.api.aspects.Aspect; 10 | import net.minecraft.world.World; 11 | import cpw.mods.fml.common.FMLLog; 12 | 13 | public class VisNetHandler { 14 | 15 | // / NODE DRAINING 16 | /** 17 | * This method drains vis from a relay or source near the passed in 18 | * location. The amount received can be less than the amount requested so 19 | * take that into account. 20 | * 21 | * @param world 22 | * @param x the x position of the draining block or entity 23 | * @param y the y position of the draining block or entity 24 | * @param z the z position of the draining block or entity 25 | * @param aspect what aspect to drain 26 | * @param amount how much to drain 27 | * @return how much was actually drained 28 | */ 29 | public static int drainVis(World world, int x, int y, int z, Aspect aspect, int amount) { 30 | 31 | int drainedAmount = 0; 32 | 33 | WorldCoordinates drainer = new WorldCoordinates(x, y, z, 34 | world.provider.dimensionId); 35 | if (!nearbyNodes.containsKey(drainer)) { 36 | calculateNearbyNodes(world, x, y, z); 37 | } 38 | 39 | ArrayList> nodes = nearbyNodes.get(drainer); 40 | if (nodes!=null && nodes.size()>0) 41 | for (WeakReference noderef : nodes) { 42 | 43 | TileVisNode node = noderef.get(); 44 | 45 | if (node == null) continue; 46 | 47 | int a = node.consumeVis(aspect, amount); 48 | drainedAmount += a; 49 | amount -= a; 50 | if (a>0) { 51 | int color = Aspect.getPrimalAspects().indexOf(aspect); 52 | generateVisEffect(world.provider.dimensionId, x, y, z, node.xCoord, node.yCoord, node.zCoord, color); 53 | } 54 | if (amount <= 0) { 55 | break; 56 | } 57 | } 58 | 59 | return drainedAmount; 60 | } 61 | 62 | static Method generateVisEffect; 63 | public static void generateVisEffect(int dim, int x, int y, int z, int x2, int y2, int z2, int color) { 64 | try { 65 | if(generateVisEffect == null) { 66 | Class fake = Class.forName("thaumcraft.common.lib.Utils"); 67 | generateVisEffect = fake.getMethod("generateVisEffect", int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class); 68 | } 69 | generateVisEffect.invoke(null, dim, x,y,z,x2,y2,z2,color); 70 | } catch(Exception ex) { 71 | FMLLog.warning("[Thaumcraft API] Could not invoke thaumcraft.common.lib.Utils method generateVisEffect"); 72 | } 73 | } 74 | 75 | public static HashMap>> sources = new HashMap>>(); 76 | 77 | public static void addSource(World world, TileVisNode vs) { 78 | HashMap> sourcelist = sources 79 | .get(world.provider.dimensionId); 80 | if (sourcelist == null) { 81 | sourcelist = new HashMap>(); 82 | } 83 | sourcelist.put(vs.getLocation(), new WeakReference(vs)); 84 | sources.put(world.provider.dimensionId, sourcelist); 85 | nearbyNodes.clear(); 86 | } 87 | 88 | public static boolean isNodeValid(WeakReference node) { 89 | if (node == null || node.get() == null || node.get().isInvalid()) 90 | return false; 91 | return true; 92 | } 93 | 94 | public static WeakReference addNode(World world, TileVisNode vn) { 95 | WeakReference ref = new WeakReference(vn); 96 | 97 | HashMap> sourcelist = sources 98 | .get(world.provider.dimensionId); 99 | if (sourcelist == null) { 100 | sourcelist = new HashMap>(); 101 | return null; 102 | } 103 | 104 | ArrayList nearby = new ArrayList(); 105 | 106 | for (WeakReference root : sourcelist.values()) { 107 | if (!isNodeValid(root)) 108 | continue; 109 | 110 | TileVisNode source = root.get(); 111 | 112 | float r = inRange(world, vn.getLocation(), source.getLocation(), 113 | vn.getRange()); 114 | if (r > 0) { 115 | nearby.add(new Object[] { source, r - vn.getRange() * 2 }); 116 | } 117 | nearby = findClosestNodes(vn, source, nearby); 118 | } 119 | 120 | float dist = Float.MAX_VALUE; 121 | TileVisNode closest = null; 122 | if (nearby.size() > 0) { 123 | for (Object[] o : nearby) { 124 | if ((Float) o[1] < dist) {// && canNodeBeSeen(vn,(TileVisNode) 125 | // o[0])) { 126 | dist = (Float) o[1]; 127 | closest = (TileVisNode) o[0]; 128 | } 129 | } 130 | } 131 | if (closest != null) { 132 | closest.getChildren().add(ref); 133 | nearbyNodes.clear(); 134 | return new WeakReference(closest); 135 | } 136 | 137 | return null; 138 | } 139 | 140 | public static ArrayList findClosestNodes(TileVisNode target, 141 | TileVisNode root, ArrayList in) { 142 | TileVisNode closestChild = null; 143 | 144 | for (WeakReference child : root.getChildren()) { 145 | TileVisNode n = child.get(); 146 | 147 | if (n != null 148 | && !n.equals(target) 149 | && !n.equals(root) 150 | && (target.getAttunement() == -1 || n.getAttunement() == -1 || n 151 | .getAttunement() == target.getAttunement())) { 152 | 153 | float r2 = inRange(n.getWorldObj(), n.getLocation(), 154 | target.getLocation(), target.getRange()); 155 | if (r2 > 0) { 156 | in.add(new Object[] { n, r2 }); 157 | } 158 | 159 | in = findClosestNodes(target, n, in); 160 | } 161 | } 162 | return in; 163 | } 164 | 165 | private static float inRange(World world, WorldCoordinates cc1, 166 | WorldCoordinates cc2, int range) { 167 | float distance = cc1.getDistanceSquaredToWorldCoordinates(cc2); 168 | return distance > range * range ? -1 : distance; 169 | } 170 | 171 | private static HashMap>> nearbyNodes = new HashMap>>(); 172 | 173 | private static void calculateNearbyNodes(World world, int x, int y, int z) { 174 | 175 | HashMap> sourcelist = sources 176 | .get(world.provider.dimensionId); 177 | if (sourcelist == null) { 178 | sourcelist = new HashMap>(); 179 | return; 180 | } 181 | 182 | ArrayList> cn = new ArrayList>(); 183 | WorldCoordinates drainer = new WorldCoordinates(x, y, z, 184 | world.provider.dimensionId); 185 | 186 | ArrayList nearby = new ArrayList(); 187 | 188 | for (WeakReference root : sourcelist.values()) { 189 | 190 | if (!isNodeValid(root)) 191 | continue; 192 | 193 | TileVisNode source = root.get(); 194 | 195 | TileVisNode closest = null; 196 | float range = Float.MAX_VALUE; 197 | 198 | float r = inRange(world, drainer, source.getLocation(), 199 | source.getRange()); 200 | if (r > 0) { 201 | range = r; 202 | closest = source; 203 | } 204 | 205 | ArrayList> children = new ArrayList>(); 206 | children = getAllChildren(source,children); 207 | 208 | for (WeakReference child : children) { 209 | TileVisNode n = child.get(); 210 | if (n != null && !n.equals(root)) { 211 | 212 | float r2 = inRange(n.getWorldObj(), n.getLocation(), 213 | drainer, n.getRange()); 214 | if (r2 > 0 && r2 < range) { 215 | range = r2; 216 | closest = n; 217 | } 218 | } 219 | } 220 | 221 | if (closest != null) { 222 | 223 | cn.add(new WeakReference(closest)); 224 | } 225 | } 226 | 227 | nearbyNodes.put(drainer, cn); 228 | } 229 | 230 | private static ArrayList> getAllChildren(TileVisNode source, ArrayList> list) { 231 | for (WeakReference child : source.getChildren()) { 232 | TileVisNode n = child.get(); 233 | if (n != null) { 234 | list.add(child); 235 | list = getAllChildren(n,list); 236 | } 237 | } 238 | return list; 239 | } 240 | 241 | // public static boolean canNodeBeSeen(TileVisNode source,TileVisNode 242 | // target) 243 | // { 244 | // double d = Math.sqrt(source.getDistanceFrom(target.xCoord, target.yCoord, 245 | // target.zCoord)); 246 | // double xd = (source.xCoord-target.xCoord) / d; 247 | // double yd = (source.yCoord-target.yCoord) / d; 248 | // double zd = (source.zCoord-target.zCoord) / d; 249 | // return source.getWorldObj().rayTraceBlocks( 250 | // Vec3.createVectorHelper(source.xCoord-xd+.5+.5, source.yCoord-yd, 251 | // source.zCoord-zd), 252 | // Vec3.createVectorHelper(target.xCoord+.5, target.yCoord+.5, 253 | // target.zCoord+.5)) == null; 254 | // } 255 | 256 | // public static HashMap> 257 | // noderef = new HashMap>(); 258 | // 259 | // public static TileVisNode getClosestNodeWithinRadius(World world, int x, 260 | // int y, int z, int radius) { 261 | // TileVisNode out = null; 262 | // WorldCoordinates wc = null; 263 | // float cd = Float.MAX_VALUE; 264 | // for (int sx = x - radius; sx <= x + radius; sx++) { 265 | // for (int sy = y - radius; sy <= y + radius; sy++) { 266 | // for (int sz = z - radius; sz <= z + radius; sz++) { 267 | // wc = new WorldCoordinates(sx,sy,sz,world.provider.dimensionId); 268 | // if (noderef.containsKey(wc)) { 269 | // float d = wc.getDistanceSquared(x, y, z); 270 | // if (d