- Added 1.7.10 Buildcraft support

- Exceptions can now log to the minetweaker log, for easier bug resolution
- /mt hand now copies to the clipboard too
- /mt hand now outputs ore dictionary entries to which it belongs
- Reducing verbosity a bit
This commit is contained in:
Stan Hebben committed 2014-10-08 14:50:50 +02:00
1 parent 86a3568e9e
commit a8aae17d8a
29 files changed
+1289 -24

No files matched your search

@@ -216,6 +216,19 @@ public class MineTweakerAPI {
getLogger().logError(message);
}
/**
* Logs an error message. Error messages indicate a real problem and
* indicate that things won't run properly. The scripting system will
* still make a best-effort attempt at executing the rest of the scripts,
* but that might cause additional errors and issues.
*
* @param message error message
* @param exception exception that was caught related to the error
*/
public static void logError(String message, Throwable exception) {
getLogger().logError(message, exception);
}
// ###################################
// ### Plugin registration methods ###
// ###################################
@@ -1,5 +1,8 @@
package minetweaker;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -124,7 +127,7 @@ public class MineTweakerImplementationAPI {
MineTweakerAPI.logCommand("Liquids:");
for (ILiquidDefinition liquid : liquids) {
MineTweakerAPI.logCommand("<" + liquid.getName() + "> -- " + liquid.getDisplayName());
MineTweakerAPI.logCommand("<liquid:" + liquid.getName() + "> -- " + liquid.getDisplayName());
}
if (player != null) {
@@ -204,7 +207,14 @@ public class MineTweakerImplementationAPI {
public void execute(String[] arguments, IPlayer player) {
IItemStack hand = player.getCurrentItem();
if (hand != null) {
player.sendChat(hand.toString());
String value = hand.toString();
player.sendChat(value);
copyToClipboard(value);
List<IOreDictEntry> entries = hand.getOres();
for (IOreDictEntry entry : entries) {
player.sendChat("Is in <ore:" + entry.getName() + ">");
}
}
}
}));
@@ -576,6 +586,16 @@ public class MineTweakerImplementationAPI {
MineTweakerAPI.apply(new AddMineTweakerCommandAction(new MineTweakerCommand(name, description, function)));
}
// ##############################
// ### Private static methods ###
// ##############################
private static void copyToClipboard(String value) {
StringSelection stringSelection = new StringSelection(value);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null);
}
// ############################
// ### Public inner classes ###
// ############################
@@ -1,5 +1,7 @@
package minetweaker.api.item;
import java.util.List;
import minetweaker.api.oredict.IOreDictEntry;
import stanhebben.zenscript.annotations.Optional;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenGetter;
@@ -40,4 +42,13 @@ public interface IItemDefinition {
*/
@ZenMethod
public IItemStack makeStack(@Optional int meta);
/**
* Returns all ore entries containing this item. Also contains ore entries
* that refer to a specific sub-item.
*
* @return
*/
@ZenGetter("ores")
public List<IOreDictEntry> getOres();
}
@@ -1,8 +1,10 @@
package minetweaker.api.item;
import java.util.List;
import minetweaker.api.block.IBlock;
import minetweaker.api.data.IData;
import minetweaker.api.liquid.ILiquidStack;
import minetweaker.api.oredict.IOreDictEntry;
import stanhebben.zenscript.annotations.OperatorType;
import stanhebben.zenscript.annotations.ZenCaster;
import stanhebben.zenscript.annotations.ZenClass;
@@ -180,4 +182,13 @@ public interface IItemStack extends IIngredient {
*/
@ZenCaster
public IBlock asBlock();
/**
* Retrieves all the ores referring to this item. Includes wildcard ore
* entries.
*
* @return ore entries containing this item stack
*/
@ZenGetter("ores")
public List<IOreDictEntry> getOres();
}
@@ -11,6 +11,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import minetweaker.runtime.ILogger;
@@ -21,14 +22,16 @@ import minetweaker.runtime.ILogger;
*/
public class FileLogger implements ILogger {
private final Writer writer;
private final PrintWriter printWriter;
public FileLogger(File output) {
try {
writer = new OutputStreamWriter(new FileOutputStream(output), "utf-8");
printWriter = new PrintWriter(writer);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException("What the heck?");
} catch (FileNotFoundException ex) {
throw new RuntimeException("File not found");
throw new RuntimeException("Could not open log file " + output);
}
}
@@ -64,8 +67,16 @@ public class FileLogger implements ILogger {
@Override
public void logError(String message) {
logError(message, null);
}
@Override
public void logError(String message, Throwable exception) {
try {
writer.write("ERROR: " + message + "\n");
if (exception != null) {
exception.printStackTrace(printWriter);
}
writer.flush();
} catch (IOException ex) {
throw new RuntimeException(ex);
@@ -76,11 +76,16 @@ public class MTLogger implements ILogger {
}
}
}
@Override
public void logError(String message) {
logError(message, null);
}
@Override
public void logError(String message, Throwable exception) {
for (ILogger logger : loggers) {
logger.logError(message);
logger.logError(message, exception);
}
String message2 = "ERROR: " + message;
@@ -24,4 +24,7 @@ public interface ILogger {
@ZenMethod
public void logError(String message);
@ZenMethod
public void logError(String message, Throwable exception);
}
@@ -137,8 +137,7 @@ public class MTTweaker implements ITweaker {
//ex.printStackTrace();
MineTweakerAPI.logError("Error parsing " + ex.getFile().getFileName() + ":" + ex.getLine() + " -- " + ex.getExplanation());
} catch (Exception ex) {
MineTweakerAPI.logError("Error loading " + script.getName() + ": " + ex.toString());
ex.printStackTrace();
MineTweakerAPI.logError("Error loading " + script.getName() + ": " + ex.toString(), ex);
}
if (reader != null) {
@@ -156,9 +155,8 @@ public class MTTweaker implements ITweaker {
// execute scripts
ZenModule module = new ZenModule(classes, MineTweakerAPI.class.getClassLoader());
module.getMain().run();
} catch (Exception ex) {
MineTweakerAPI.logError("Error executing " + script.getGroupName() + ": " + ex.getMessage());
ex.printStackTrace();
} catch (Throwable ex) {
MineTweakerAPI.logError("Error executing " + script.getGroupName() + ": " + ex.getMessage(), ex);
}
}
}
@@ -391,6 +391,9 @@ public class MineTweakerMC {
* @return MCF fluid stack
*/
public static FluidStack getLiquidStack(ILiquidStack stack) {
if (stack == null)
return null;
return (FluidStack) stack.getInternal();
}
@@ -147,10 +147,10 @@ public class MineTweakerMod {
for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) {
if (imcMessage.key.equalsIgnoreCase("addMineTweakerScript")) {
if (imcMessage.isStringMessage()) {
scriptsIMC.add("imc", imcMessage.getStringValue());
scriptsIMC.add(imcMessage.getSender() + "::imc", imcMessage.getStringValue());
} else if (imcMessage.isNBTMessage()) {
NBTTagCompound message = imcMessage.getNBTValue();
scriptsIMC.add(message.getString("name"), message.getString("content"));
scriptsIMC.add(imcMessage.getSender() + "::" + message.getString("name"), message.getString("content"));
}
}
}
@@ -6,11 +6,16 @@
package minetweaker.mc164.item;
import java.util.ArrayList;
import java.util.List;
import minetweaker.MineTweakerAPI;
import minetweaker.api.item.IItemDefinition;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import minetweaker.api.oredict.IOreDictEntry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
/**
*
@@ -38,6 +43,22 @@ public class MCItemDefinition implements IItemDefinition {
return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta));
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == item) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
// #############################
@@ -6,6 +6,7 @@
package minetweaker.mc164.item;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import minetweaker.MineTweakerAPI;
@@ -24,6 +25,7 @@ import minetweaker.api.item.IngredientOr;
import minetweaker.api.item.WeightedItemStack;
import minetweaker.api.liquid.ILiquidStack;
import static minetweaker.api.minecraft.MineTweakerMC.getItemStack;
import minetweaker.api.oredict.IOreDictEntry;
import minetweaker.api.player.IPlayer;
import minetweaker.mc164.actions.SetTranslationAction;
import minetweaker.mc164.block.MCItemBlock;
@@ -265,6 +267,23 @@ public class MCItemStack implements IItemStack {
return stack;
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == stack.getItem()
&& (is.getItemDamage() == OreDictionary.WILDCARD_VALUE || is.getItemDamage() == stack.getItemDamage())) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
// #############################
@@ -137,6 +137,33 @@ public class MineTweakerMC {
return new MCItemStack(new ItemStack(item, 1, OreDictionary.WILDCARD_VALUE));
}
/**
* Converts a Minecraft ingredient to a MineTweaker ingredient.
*
* @param ingredient minecraft ingredient
* @return minetweaker ingredient
*/
public static IIngredient getIIngredient(Object ingredient) {
if (ingredient instanceof String) {
return MineTweakerAPI.oreDict.get((String) ingredient);
} else if (ingredient instanceof Item) {
return getIItemStack(new ItemStack((Item) ingredient, 1, 0));
} else if (ingredient instanceof ItemStack) {
return getIItemStack((ItemStack) ingredient);
} else {
throw new IllegalArgumentException("Not a valid ingredient: " + ingredient);
}
}
public static ItemStack[] getExamples(IIngredient ingredient) {
List<IItemStack> examples = ingredient.getItems();
ItemStack[] result = new ItemStack[examples.size()];
for (int i = 0; i < examples.size(); i++) {
result[i] = MineTweakerMC.getItemStack(examples.get(i));
}
return result;
}
/**
* Constructs an item stack with given item, damage and amount.
*
@@ -395,6 +422,9 @@ public class MineTweakerMC {
* @return MCF fluid stack
*/
public static FluidStack getLiquidStack(ILiquidStack stack) {
if (stack == null)
return null;
return (FluidStack) stack.getInternal();
}
}
@@ -51,7 +51,7 @@ import net.minecraftforge.common.MinecraftForge;
*
* @author Stan Hebben
*/
@Mod(modid = MineTweakerMod.MODID, version = "${version}")
@Mod(modid = MineTweakerMod.MODID, version = "3.0.9")
public class MineTweakerMod {
public static final String MODID = "MineTweaker3";
public static final String MCVERSION = "1.7.10";
@@ -62,13 +62,15 @@ public class MineTweakerMod {
"minetweaker.mods.ic2.ClassRegistry",
"minetweaker.mods.nei.ClassRegistry",
"minetweaker.mods.mfr.ClassRegistry",
"minetweaker.mods.gregtech.ClassRegistry"
"minetweaker.mods.gregtech.ClassRegistry",
"minetweaker.mods.buildcraft.ClassRegistry"
};
private static final String[] REGISTRY_DESCRIPTIONS = {
"IC2 mod support",
"NEI mod support",
"MFR mod support",
"GregTech mod support"
"GregTech mod support",
"Buildcraft mod support"
};
static {
@@ -122,10 +124,10 @@ public class MineTweakerMod {
for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) {
if (imcMessage.key.equalsIgnoreCase("addMineTweakerScript")) {
if (imcMessage.isStringMessage()) {
scriptsIMC.add("imc", imcMessage.getStringValue());
scriptsIMC.add(imcMessage.getSender() + "::imc", imcMessage.getStringValue());
} else if (imcMessage.isNBTMessage()) {
NBTTagCompound message = imcMessage.getNBTValue();
scriptsIMC.add(message.getString("name"), message.getString("content"));
scriptsIMC.add(imcMessage.getSender() + "::" + message.getString("name"), message.getString("content"));
}
}
}
@@ -6,11 +6,16 @@
package minetweaker.mc1710.item;
import java.util.ArrayList;
import java.util.List;
import minetweaker.MineTweakerAPI;
import minetweaker.api.item.IItemDefinition;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import minetweaker.api.oredict.IOreDictEntry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
/**
*
@@ -39,6 +44,22 @@ public class MCItemDefinition implements IItemDefinition {
public IItemStack makeStack(int meta) {
return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta));
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == item) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
@@ -6,6 +6,7 @@
package minetweaker.mc1710.item;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import minetweaker.MineTweakerAPI;
@@ -24,6 +25,7 @@ import minetweaker.api.item.IngredientOr;
import minetweaker.api.item.WeightedItemStack;
import minetweaker.api.liquid.ILiquidStack;
import static minetweaker.api.minecraft.MineTweakerMC.getItemStack;
import minetweaker.api.oredict.IOreDictEntry;
import minetweaker.api.player.IPlayer;
import minetweaker.mc1710.actions.SetTranslationAction;
import minetweaker.mc1710.block.MCItemBlock;
@@ -264,6 +266,23 @@ public class MCItemStack implements IItemStack {
}
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == stack.getItem()
&& (is.getItemDamage() == OreDictionary.WILDCARD_VALUE || is.getItemDamage() == stack.getItemDamage())) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
// #############################
@@ -76,7 +76,6 @@ public class RecipeConverter {
// construct recipe
if (type == TYPE_BASIC) {
System.out.println("Converted to basic recipe");
ItemStack[] basicIngredients = new ItemStack[recipe.getHeight() * recipe.getWidth()];
for (int i = 0; i < ingredients.length; i++) {
basicIngredients[posx[i] + posy[i] * recipe.getWidth()] = getItemStack(ingredients[i]);
@@ -84,7 +83,6 @@ public class RecipeConverter {
return new ShapedRecipeBasic(basicIngredients, recipe);
} else if (type == TYPE_ORE) {
System.out.println("Converted to ore recipe");
Object[] converted = new Object[recipe.getHeight() * recipe.getWidth()];
for (int i = 0; i < ingredients.length; i++) {
converted[posx[i] + posy[i] * recipe.getWidth()] = ingredients[i].getInternal();
@@ -117,7 +115,6 @@ public class RecipeConverter {
return new ShapedRecipeOre(rarguments.toArray(), recipe);
} else {
System.out.println("Converted to advanced recipe");
return new ShapedRecipeAdvanced(recipe);
}
}
@@ -0,0 +1,42 @@
import minetweaker.tasks.RegisterZenClassesTask;
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
}
}
apply plugin: 'forge'
minecraft {
version = forgeVersion1710
}
version = "1.0"
archivesBaseName = project.projectDir.name
dependencies {
compile project(':ZenScript')
compile project(':MineTweaker3-API')
compile project(':MineTweaker3-MC1710-Main')
compile files('libs/buildcraft-6.0.18-dev.jar')
}
task makeRegistry(type: RegisterZenClassesTask) {
inputDir = file('build/classes/main')
outputDir = file('build/classes/main')
className = 'minetweaker.mods.buildcraft.ClassRegistry'
}
tasks.jar.dependsOn(makeRegistry)
@@ -0,0 +1,184 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package minetweaker.mods.buildcraft;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.core.recipes.AssemblyRecipeManager;
import buildcraft.core.recipes.AssemblyRecipeManager.AssemblyRecipe;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import minetweaker.IUndoableAction;
import minetweaker.MineTweakerAPI;
import minetweaker.annotations.ModOnly;
import minetweaker.api.item.IIngredient;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import stanhebben.zenscript.annotations.Optional;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
/**
*
* @author Stan
*/
@ZenClass("mods.buildcraft.AssemblyTable")
@ModOnly("BuildCraft|Core")
public class AssemblyTable {
@ZenMethod
public static void addRecipe(IItemStack output, double energy, IIngredient[] ingredients) {
MineTweakerAPI.apply(new AddRecipeAction(output, energy, ingredients));
}
@ZenMethod
public static void remove(IIngredient output) {
removeRecipe(output, null, false);
}
@ZenMethod
public static void removeRecipe(IIngredient output, @Optional IIngredient[] ingredients, @Optional boolean wildcard) {
List<AssemblyRecipe> toRemove = new ArrayList<AssemblyRecipe>();
outer: for (AssemblyRecipe recipe : ((AssemblyRecipeManager) BuildcraftRecipes.assemblyTable).getRecipes()) {
if (output.matches(MineTweakerMC.getIItemStack(recipe.getOutput()))
&& ingredientsMatch(recipe, ingredients, wildcard)) {
toRemove.add(recipe);
}
}
for (AssemblyRecipe recipe : toRemove) {
MineTweakerAPI.apply(new RemoveRecipeAction(recipe));
}
}
/**
* Checks if ingredients from the recipe match with the given ingredients.
*
* @param recipe recipe to check
* @param ingredients required ingredients
* @param wildcard true if there can be more ingredients in the recipe than given, false otherwise
* @return matching result
*/
private static boolean ingredientsMatch(AssemblyRecipe recipe, IIngredient[] ingredients, boolean wildcard) {
if (ingredients == null)
return true;
int matchedIngredients = 0;
boolean[] matched = new boolean[ingredients.length];
checkIngredient: for (int i = 0; i < recipe.getInputs().length; i++) {
Object ingredientObject = recipe.getInputs()[i];
if (ingredientObject instanceof Number)
continue;
IIngredient recipeIngredient = MineTweakerMC.getIIngredient(recipe.getInputs()[i]);
for (int j = 0; j < ingredients.length; j++) {
if (!matched[j] && ingredients[j].contains(recipeIngredient)) {
matched[j] = true;
matchedIngredients++;
continue checkIngredient;
}
}
if (!wildcard)
return false;
}
return matchedIngredients == ingredients.length;
}
// ######################
// ### Action classes ###
// ######################
private static class AddRecipeAction implements IUndoableAction {
private final IItemStack output;
private final AssemblyRecipe recipe;
public AddRecipeAction(IItemStack output, double energy, IIngredient[] ingredients) {
this.output = output;
Object[] mcIngredients = new Object[ingredients.length];
for (int i = 0; i < ingredients.length; i++) {
mcIngredients[i] = ingredients[i].getInternal();
if (mcIngredients[i] == null) {
throw new IllegalArgumentException("Not a valid assembly table ingredient");
}
}
recipe = new AssemblyRecipe(MineTweakerMC.getItemStack(output), energy, mcIngredients);
}
@Override
public void apply() {
((AssemblyRecipeManager) BuildcraftRecipes.assemblyTable).getRecipes().add(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
BuildcraftRecipes.assemblyTable.getRecipes().remove(recipe);
}
@Override
public String describe() {
return "Adding assembly table recipe for " + output;
}
@Override
public String describeUndo() {
return "Removing assembly table recipe for " + output;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveRecipeAction implements IUndoableAction {
private final AssemblyRecipe recipe;
public RemoveRecipeAction(AssemblyRecipe recipe) {
this.recipe = recipe;
}
@Override
public void apply() {
BuildcraftRecipes.assemblyTable.getRecipes().remove(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
((AssemblyRecipeManager) BuildcraftRecipes.assemblyTable).getRecipes().add(recipe);
}
@Override
public String describe() {
return "Removing assembly table recipe for " + MineTweakerMC.getIItemStack(recipe.getOutput());
}
@Override
public String describeUndo() {
return "Restoring assembly table recipe for " + MineTweakerMC.getIItemStack(recipe.getOutput());
}
@Override
public Object getOverrideKey() {
return null;
}
}
}
@@ -0,0 +1,375 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package minetweaker.mods.buildcraft;
import buildcraft.api.core.StackKey;
import buildcraft.api.fuels.IronEngineCoolant;
import buildcraft.api.fuels.IronEngineFuel;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;
import minetweaker.IUndoableAction;
import minetweaker.MineTweakerAPI;
import minetweaker.annotations.ModOnly;
import minetweaker.api.item.IIngredient;
import minetweaker.api.item.IItemStack;
import minetweaker.api.liquid.ILiquidStack;
import minetweaker.api.minecraft.MineTweakerMC;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
/**
*
* @author Stan
*/
@ZenClass("mods.buildcraft.Fuels")
@ModOnly("BuildCraft|Core")
public class Fuels {
private static final Constructor CONSTRUCT_FUEL;
static {
Constructor newFuel = null;
try {
newFuel = IronEngineFuel.Fuel.class.getDeclaredConstructor(Fluid.class, float.class, int.class);
newFuel.setAccessible(true);
} catch (NoSuchMethodException ex) {
MineTweakerAPI.logError("Could not load combustion engine fuel constructor", ex);
} catch (SecurityException ex) {
MineTweakerAPI.logError("Could not load combustion engine fuel constructor", ex);
}
CONSTRUCT_FUEL = newFuel;
}
@ZenMethod
public static void addCombustionEngineFuel(ILiquidStack fuel, double powerPerCycle, int totalBurningTime) {
MineTweakerAPI.apply(new AddFuelAction(fuel, powerPerCycle, totalBurningTime));
}
@ZenMethod
public static void removeCombustionEngineFuel(ILiquidStack fuel) {
Fluid fluid = MineTweakerMC.getLiquidStack(fuel).getFluid();
if (IronEngineFuel.fuels.containsKey(fluid.getName())) {
MineTweakerAPI.apply(new RemoveFuelAction(fluid.getName(), IronEngineFuel.fuels.get(fluid.getName())));
} else {
MineTweakerAPI.logWarning("No such iron engine fuel: " + fluid.getName());
}
}
@ZenMethod
public static void addCombustionEngineCoolant(ILiquidStack coolant, float coolingPerMB) {
MineTweakerAPI.apply(new AddLiquidCoolantAction(coolant.getName(), new MTCoolant(coolingPerMB)));
}
@ZenMethod
public static void addCoolantItem(IItemStack coolantItem, ILiquidStack coolantLiquid) {
MineTweakerAPI.apply(new AddCoolantItemAction(new StackKey(MineTweakerMC.getItemStack(coolantItem)), MineTweakerMC.getLiquidStack(coolantLiquid)));
}
@ZenMethod
public static void removeCombustionEngineCoolant(ILiquidStack coolant) {
FluidStack fluid = MineTweakerMC.getLiquidStack(coolant);
if (IronEngineCoolant.isCoolant(fluid.getFluid())) {
MineTweakerAPI.apply(new RemoveLiquidCoolantAction(fluid.getFluid().getName(), IronEngineCoolant.getCoolant(fluid)));
} else {
MineTweakerAPI.logWarning("No such iron engine coolant: " + fluid.getFluid().getName());
}
}
@ZenMethod
public static void removeCoolantItem(IIngredient item) {
int numRemoved = 0;
for (IItemStack itemStack : item.getItems()) {
StackKey key = new StackKey(MineTweakerMC.getItemStack(itemStack));
if (IronEngineCoolant.solidCoolants.containsKey(key)) {
MineTweakerAPI.apply(new RemoveCoolantItemAction(key, IronEngineCoolant.solidCoolants.get(key)));
numRemoved++;
}
}
if (numRemoved == 0) {
MineTweakerAPI.logWarning("No such iron engine coolant: " + item);
}
}
// ######################
// ### Action classes ###
// ######################
private static class AddFuelAction implements IUndoableAction {
private final String fuelName;
private final IronEngineFuel.Fuel fuel;
public AddFuelAction(ILiquidStack fuel, double powerPerCycle, int totalBurningTime) {
fuelName = fuel.getName();
IronEngineFuel.Fuel ieFuel = null;
try {
if (CONSTRUCT_FUEL == null)
System.out.println("No constructor for fuel");
ieFuel = (IronEngineFuel.Fuel) CONSTRUCT_FUEL.newInstance(MineTweakerMC.getLiquidStack(fuel).getFluid(), (float) powerPerCycle, totalBurningTime);
} catch (InstantiationException ex) {
Logger.getLogger(Fuels.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Fuels.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Fuels.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(Fuels.class.getName()).log(Level.SEVERE, null, ex);
}
this.fuel = ieFuel;
}
@Override
public void apply() {
IronEngineFuel.fuels.put(fuelName, fuel);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
IronEngineFuel.fuels.remove(fuelName);
}
@Override
public String describe() {
return "Adding iron engine fuel " + fuelName;
}
@Override
public String describeUndo() {
return "Removing iron engine fuel " + fuelName;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveFuelAction implements IUndoableAction {
private final String fuelName;
private final IronEngineFuel.Fuel fuel;
public RemoveFuelAction(String fuelName, IronEngineFuel.Fuel fuel) {
this.fuelName = fuelName;
this.fuel = fuel;
}
@Override
public void apply() {
IronEngineFuel.fuels.remove(fuelName);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
IronEngineFuel.fuels.put(fuelName, fuel);
}
@Override
public String describe() {
return "Removing iron engine fuel " + fuelName;
}
@Override
public String describeUndo() {
return "Restoring iron engine fuel " + fuelName;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class AddLiquidCoolantAction implements IUndoableAction {
private final String liquid;
private final IronEngineCoolant.Coolant coolant;
public AddLiquidCoolantAction(String liquid, IronEngineCoolant.Coolant coolant) {
this.liquid = liquid;
this.coolant = coolant;
}
@Override
public void apply() {
IronEngineCoolant.liquidCoolants.put(liquid, coolant);
}
@Override
public boolean canUndo() {
return false;
}
@Override
public void undo() {
IronEngineCoolant.liquidCoolants.remove(liquid);
}
@Override
public String describe() {
return "Adding iron engine coolant " + liquid;
}
@Override
public String describeUndo() {
return "Removing iron engine coolant " + liquid;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class AddCoolantItemAction implements IUndoableAction {
private final StackKey item;
private final FluidStack liquid;
public AddCoolantItemAction(StackKey item, FluidStack liquid) {
this.item = item;
this.liquid = liquid;
}
@Override
public void apply() {
IronEngineCoolant.solidCoolants.put(item, liquid);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
IronEngineCoolant.solidCoolants.remove(item);
}
@Override
public String describe() {
return "Adding iron engine coolant item " + MineTweakerMC.getIItemStack(item.stack);
}
@Override
public String describeUndo() {
return "Removing iron engine coolant item " + MineTweakerMC.getIItemStack(item.stack);
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveLiquidCoolantAction implements IUndoableAction {
private final String liquid;
private final IronEngineCoolant.Coolant coolant;
public RemoveLiquidCoolantAction(String liquid, IronEngineCoolant.Coolant coolant) {
this.liquid = liquid;
this.coolant = coolant;
}
@Override
public void apply() {
IronEngineCoolant.liquidCoolants.remove(liquid);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
IronEngineCoolant.liquidCoolants.put(liquid, coolant);
}
@Override
public String describe() {
return "Removing iron engine coolant " + liquid;
}
@Override
public String describeUndo() {
return "Restoring iron engine coolant " + liquid;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveCoolantItemAction implements IUndoableAction {
private final StackKey item;
private final FluidStack liquid;
public RemoveCoolantItemAction(StackKey item, FluidStack liquid) {
this.item = item;
this.liquid = liquid;
}
@Override
public void apply() {
IronEngineCoolant.solidCoolants.remove(item);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
IronEngineCoolant.solidCoolants.put(item, liquid);
}
@Override
public String describe() {
return "Removing iron engine coolant item " + item.stack.getDisplayName();
}
@Override
public String describeUndo() {
return "Restoring iron engine coolant item " + item.stack.getDisplayName();
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class MTCoolant implements IronEngineCoolant.Coolant {
private final float coolingPerMB;
public MTCoolant(float coolingPerMB) {
this.coolingPerMB = coolingPerMB;
}
@Override
public float getDegreesCoolingPerMB(float f) {
return coolingPerMB;
}
}
}
@@ -0,0 +1,17 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package minetweaker.mods.buildcraft;
import minetweaker.api.item.IItemStack;
/**
*
* @author Stan
*/
public interface IIntegrationRecipeFunction {
public IItemStack recipe(IItemStack output, IItemStack inputA, IItemStack inputB);
}
@@ -0,0 +1,217 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package minetweaker.mods.buildcraft;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.api.recipes.IIntegrationRecipeManager.IIntegrationRecipe;
import java.util.ArrayList;
import java.util.List;
import minetweaker.IUndoableAction;
import minetweaker.MineTweakerAPI;
import minetweaker.annotations.ModOnly;
import minetweaker.api.item.IIngredient;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import net.minecraft.item.ItemStack;
import stanhebben.zenscript.annotations.Optional;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
/**
*
* @author Stan
*/
@ZenClass("mods.buildcraft.IntegrationTable")
@ModOnly("BuildCraft|Core")
public class IntegrationTable {
@ZenMethod
public static void addRecipe(IItemStack output, double energy, IIngredient inputA, IIngredient inputB, @Optional IIntegrationRecipeFunction function) {
MineTweakerAPI.apply(new AddRecipeAction(output, energy, inputA, inputB, function));
}
@ZenMethod
public static void remove(IIngredient output) {
removeRecipe(output, null, null);
}
@ZenMethod
public static void removeRecipe(IIngredient output, @Optional IIngredient inputA, @Optional IIngredient inputB) {
List<IIntegrationRecipe> toRemove = new ArrayList<IIntegrationRecipe>();
outer: for (IIntegrationRecipe recipe : BuildcraftRecipes.integrationTable.getRecipes()) {
for (ItemStack component : recipe.getComponents()) {
if (!output.matches(MineTweakerMC.getIItemStack(component)))
continue outer;
if (inputA != null) {
for (ItemStack example1 : recipe.getExampleInputsA()) {
if (!inputA.matches(MineTweakerMC.getIItemStack(example1))) {
continue outer;
}
}
}
if (inputB != null) {
for (ItemStack example2 : recipe.getExampleInputsB()) {
if (!inputB.matches(MineTweakerMC.getIItemStack(example2))) {
continue outer;
}
}
}
toRemove.add(recipe);
}
}
for (IIntegrationRecipe recipe : toRemove) {
MineTweakerAPI.apply(new RemoveRecipeAction(recipe));
}
}
// ######################
// ### Action Classes ###
// ######################
private static class AddRecipeAction implements IUndoableAction {
private final MTIntegrationRecipe recipe;
public AddRecipeAction(IItemStack output, double energy, IIngredient inputA, IIngredient inputB, IIntegrationRecipeFunction function) {
recipe = new MTIntegrationRecipe(output, energy, inputA, inputB, function);
}
@Override
public void apply() {
BuildcraftRecipes.integrationTable.addRecipe(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
BuildcraftRecipes.integrationTable.getRecipes().remove(recipe);
}
@Override
public String describe() {
return "Adding integration table recipe for " + recipe.output;
}
@Override
public String describeUndo() {
return "Removing integration table recipe for " + recipe.output;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveRecipeAction implements IUndoableAction {
private final IIntegrationRecipe recipe;
public RemoveRecipeAction(IIntegrationRecipe recipe) {
this.recipe = recipe;
}
@Override
public void apply() {
BuildcraftRecipes.integrationTable.getRecipes().remove(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
BuildcraftRecipes.integrationTable.addRecipe(recipe);
}
@Override
public String describe() {
return "Removing integration table recipe for " + MineTweakerMC.getIItemStack(recipe.getComponents()[0]);
}
@Override
public String describeUndo() {
return "Restoring integration table recipe for " + MineTweakerMC.getIItemStack(recipe.getComponents()[0]);
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class MTIntegrationRecipe implements IIntegrationRecipe {
private final IItemStack output;
private final ItemStack[] components;
private final double energy;
private final IIngredient inputA;
private final ItemStack[] inputAExamples;
private final IIngredient inputB;
private final ItemStack[] inputBExamples;
private final IIntegrationRecipeFunction function;
private MTIntegrationRecipe(IItemStack output, double energy, IIngredient inputA, IIngredient inputB, IIntegrationRecipeFunction function) {
this.output = output;
this.components = new ItemStack[] { MineTweakerMC.getItemStack(output) };
this.energy = energy;
this.inputA = inputA;
this.inputAExamples = MineTweakerMC.getExamples(inputA);
this.inputB = inputB;
this.inputBExamples = MineTweakerMC.getExamples(inputB);
this.function = function;
}
@Override
public double getEnergyCost() {
return energy;
}
@Override
public boolean isValidInputA(ItemStack is) {
return inputA.matches(MineTweakerMC.getIItemStack(is));
}
@Override
public boolean isValidInputB(ItemStack is) {
return inputB.matches(MineTweakerMC.getIItemStack(is));
}
@Override
public ItemStack getOutputForInputs(ItemStack is, ItemStack is1, ItemStack[] iss) {
if (function != null) {
IItemStack actualInputA = MineTweakerMC.getIItemStack(is);
IItemStack actualInputB = MineTweakerMC.getIItemStack(is1);
return MineTweakerMC.getItemStack(function.recipe(output, actualInputA, actualInputB));
} else {
return MineTweakerMC.getItemStack(output);
}
}
@Override
public ItemStack[] getComponents() {
return components;
}
@Override
public ItemStack[] getExampleInputsA() {
return inputAExamples;
}
@Override
public ItemStack[] getExampleInputsB() {
return inputBExamples;
}
}
}
@@ -0,0 +1,202 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package minetweaker.mods.buildcraft;
import buildcraft.api.recipes.BuildcraftRecipes;
import buildcraft.core.recipes.RefineryRecipeManager;
import buildcraft.core.recipes.RefineryRecipeManager.RefineryRecipe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import minetweaker.IUndoableAction;
import minetweaker.MineTweakerAPI;
import minetweaker.annotations.ModOnly;
import minetweaker.api.liquid.ILiquidStack;
import minetweaker.api.minecraft.MineTweakerMC;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import stanhebben.zenscript.annotations.Optional;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
/**
*
* @author Stan
*/
@ZenClass("mods.buildcraft.Refinery")
@ModOnly("BuildCraft|Core")
public class Refinery {
private static final Constructor CONSTRUCT_REFINERYRECIPE;
private static final Field REFINERYRECIPEMANAGER_RECIPES;
static {
Constructor constructor = null;
try {
constructor = RefineryRecipe.class.getDeclaredConstructor(FluidStack.class, FluidStack.class, FluidStack.class, int.class, int.class);
constructor.setAccessible(true);
} catch (NoSuchMethodException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
}
Field recipes = null;
try {
recipes = RefineryRecipeManager.class.getDeclaredField("recipes");
recipes.setAccessible(true);
} catch (NoSuchFieldException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
}
CONSTRUCT_REFINERYRECIPE = constructor;
REFINERYRECIPEMANAGER_RECIPES = recipes;
}
@ZenMethod
public static void addRecipe(ILiquidStack output, int energyPerMB, int ticksPerMB, ILiquidStack input1, @Optional ILiquidStack input2) {
MineTweakerAPI.apply(new AddRecipeAction(output, energyPerMB, ticksPerMB, input1, input2));
}
@ZenMethod
public static void remove(ILiquidStack output) {
Fluid fluid = MineTweakerMC.getLiquidStack(output).getFluid();
List<RefineryRecipe> toRemove = new ArrayList<RefineryRecipe>();
for (RefineryRecipe recipe : ((RefineryRecipeManager) BuildcraftRecipes.refinery).getRecipes()) {
if (recipe.getResult().getFluid() == fluid) {
toRemove.add(recipe);
}
}
for (RefineryRecipe recipe : toRemove) {
MineTweakerAPI.apply(new RemoveRecipeAction(recipe));
}
}
private static SortedSet<RefineryRecipe> getRecipes() {
try {
return (SortedSet<RefineryRecipe>) REFINERYRECIPEMANAGER_RECIPES.get((RefineryRecipeManager) BuildcraftRecipes.refinery);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
}
throw new RuntimeException("Refinery recipes unavailable");
}
// ######################
// ### Action Classes ###
// ######################
private static class AddRecipeAction implements IUndoableAction {
private final ILiquidStack output;
private final RefineryRecipe recipe;
public AddRecipeAction(ILiquidStack output, int energyPerMB, int ticksPerMB, ILiquidStack input1, ILiquidStack input2) {
this.output = output;
RefineryRecipe rrecipe = null;
try {
rrecipe = (RefineryRecipe) CONSTRUCT_REFINERYRECIPE.newInstance(
MineTweakerMC.getLiquidStack(input1),
MineTweakerMC.getLiquidStack(input2),
MineTweakerMC.getLiquidStack(output),
energyPerMB,
ticksPerMB);
} catch (InstantiationException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(Refinery.class.getName()).log(Level.SEVERE, null, ex);
}
recipe = rrecipe;
}
@Override
public void apply() {
getRecipes().add(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
getRecipes().add(recipe);
}
@Override
public String describe() {
return "Adding refinery recipe for " + output;
}
@Override
public String describeUndo() {
return "Removing refinery recipe for " + output;
}
@Override
public Object getOverrideKey() {
return null;
}
}
private static class RemoveRecipeAction implements IUndoableAction {
private final RefineryRecipe recipe;
public RemoveRecipeAction(RefineryRecipe recipe) {
this.recipe = recipe;
}
@Override
public void apply() {
getRecipes().remove(recipe);
}
@Override
public boolean canUndo() {
return true;
}
@Override
public void undo() {
getRecipes().add(recipe);
}
@Override
public String describe() {
return "Removing refinery recipe for "
+ recipe.getResult().getFluid().getLocalizedName(recipe.getResult());
}
@Override
public String describeUndo() {
return "Restoring refinery recipe for "
+ recipe.getResult().getFluid().getLocalizedName(recipe.getResult());
}
@Override
public Object getOverrideKey() {
return null;
}
}
}
@@ -392,6 +392,9 @@ public class MineTweakerMC {
* @return MCF fluid stack
*/
public static FluidStack getLiquidStack(ILiquidStack stack) {
if (stack == null)
return null;
return (FluidStack) stack.getInternal();
}
}
@@ -111,10 +111,10 @@ public class MineTweakerMod {
for (final FMLInterModComms.IMCMessage imcMessage : event.getMessages()) {
if (imcMessage.key.equalsIgnoreCase("addMineTweakerScript")) {
if (imcMessage.isStringMessage()) {
scriptsIMC.add("imc", imcMessage.getStringValue());
scriptsIMC.add(imcMessage.getSender() + "::imc", imcMessage.getStringValue());
} else if (imcMessage.isNBTMessage()) {
NBTTagCompound message = imcMessage.getNBTValue();
scriptsIMC.add(message.getString("name"), message.getString("content"));
scriptsIMC.add(imcMessage.getSender() + "::" + message.getString("name"), message.getString("content"));
}
}
}
@@ -6,11 +6,16 @@
package minetweaker.mc172.item;
import java.util.ArrayList;
import java.util.List;
import minetweaker.MineTweakerAPI;
import minetweaker.api.item.IItemDefinition;
import minetweaker.api.item.IItemStack;
import minetweaker.api.minecraft.MineTweakerMC;
import minetweaker.api.oredict.IOreDictEntry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
/**
*
@@ -40,6 +45,22 @@ public class MCItemDefinition implements IItemDefinition {
return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta));
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == item) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
// #############################
@@ -6,6 +6,7 @@
package minetweaker.mc172.item;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import minetweaker.MineTweakerAPI;
@@ -24,6 +25,7 @@ import minetweaker.api.item.IngredientOr;
import minetweaker.api.item.WeightedItemStack;
import minetweaker.api.liquid.ILiquidStack;
import static minetweaker.api.minecraft.MineTweakerMC.getItemStack;
import minetweaker.api.oredict.IOreDictEntry;
import minetweaker.api.player.IPlayer;
import minetweaker.mc172.actions.SetTranslationAction;
import minetweaker.mc172.block.MCItemBlock;
@@ -264,6 +266,23 @@ public class MCItemStack implements IItemStack {
return stack;
}
@Override
public List<IOreDictEntry> getOres() {
List<IOreDictEntry> result = new ArrayList<IOreDictEntry>();
for (String key : OreDictionary.getOreNames()) {
for (ItemStack is : OreDictionary.getOres(key)) {
if (is.getItem() == stack.getItem()
&& (is.getItemDamage() == OreDictionary.WILDCARD_VALUE || is.getItemDamage() == stack.getItemDamage())) {
result.add(MineTweakerAPI.oreDict.get(key));
break;
}
}
}
return result;
}
// #############################
// ### Object implementation ###
// #############################
+3 -2
View File
@@ -2,7 +2,7 @@
// ### Global settings ###
// #######################
ext.mineTweakerVersion = "3.0.8B"
ext.mineTweakerVersion = "3.0.9"
ext.mineTweakerDebug = "false"
ext.javaToolsJar = new File("C:/Program Files/Java/jdk1.8.0_05/lib/tools.jar")
@@ -41,5 +41,6 @@ ext.projects1710 = [
'MineTweaker3-MC1710-Mod-IC2',
'MineTweaker3-MC1710-Mod-NEI',
'MineTweaker3-MC1710-Mod-MFR',
'MineTweaker3-MC1710-Mod-GregTech'
'MineTweaker3-MC1710-Mod-GregTech',
'MineTweaker3-MC1710-Mod-Buildcraft'
]