mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-08-10 17:55:44 +00:00
i spent all afternoon in a hole
This commit is contained in:
parent
e42bb12984
commit
0074c20f91
@ -12,6 +12,10 @@
|
|||||||
* When cutting down hemp, willows, and other NTM double plants, only the top part will be cut off, no matter where the thresher touches it
|
* When cutting down hemp, willows, and other NTM double plants, only the top part will be cut off, no matter where the thresher touches it
|
||||||
* Can also harvest items from sunflowers and tall grass without breaking the blocks
|
* Can also harvest items from sunflowers and tall grass without breaking the blocks
|
||||||
* Can also handle tall plants like cacti and sugar cane
|
* Can also handle tall plants like cacti and sugar cane
|
||||||
|
* New big-ass tank
|
||||||
|
* Successor to the BAT9k
|
||||||
|
* Larger footprint, way more storage space
|
||||||
|
* Needs to be placed on a proper foundation or else it'll sink into the ground
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
* RoR graphs can now have their min and max bounds set to a fixed number
|
* RoR graphs can now have their min and max bounds set to a fixed number
|
||||||
@ -29,7 +33,7 @@
|
|||||||
* Increased the yield of lye from wood ash
|
* Increased the yield of lye from wood ash
|
||||||
* All fluid tanks larger than barrels now have dynamic IO speed instead of providing their entire contents instantly
|
* All fluid tanks larger than barrels now have dynamic IO speed instead of providing their entire contents instantly
|
||||||
* Tank fill will slow down the fuller the tank becomes, tank drain also slow downs as it gets emptier
|
* Tank fill will slow down the fuller the tank becomes, tank drain also slow downs as it gets emptier
|
||||||
* This means that multiple tanks in IO mode in the same network will still ping pong, but instead of firing their entire contents over the network, they will even out
|
* This means that multiple tanks in IO mode in the same network will still ping pong, but only a small portion of fluid will be "lost" (i.e. invisible due to subtick transfer operations)
|
||||||
* The stinger is now classified as a special weapon
|
* The stinger is now classified as a special weapon
|
||||||
* The carbine can now take a scope
|
* The carbine can now take a scope
|
||||||
* The battery socket now renders supports when a block is placed on top of it, allowing somewhat aesthetic stacking of sockets
|
* The battery socket now renders supports when a block is placed on top of it, allowing somewhat aesthetic stacking of sockets
|
||||||
|
|||||||
@ -778,6 +778,7 @@ public class ModBlocks {
|
|||||||
public static Block radio_torch_reader;
|
public static Block radio_torch_reader;
|
||||||
public static Block radio_torch_controller;
|
public static Block radio_torch_controller;
|
||||||
public static Block radio_telex;
|
public static Block radio_telex;
|
||||||
|
public static Block radio_autocal;
|
||||||
public static Block oc_cable_paintable;
|
public static Block oc_cable_paintable;
|
||||||
|
|
||||||
public static Block conveyor;
|
public static Block conveyor;
|
||||||
@ -1894,6 +1895,7 @@ public class ModBlocks {
|
|||||||
radio_torch_reader = new RadioTorchReader().setBlockName("radio_torch_reader").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":rtty_reader");
|
radio_torch_reader = new RadioTorchReader().setBlockName("radio_torch_reader").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":rtty_reader");
|
||||||
radio_torch_controller = new RadioTorchController().setBlockName("radio_torch_controller").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":rtty_controller");
|
radio_torch_controller = new RadioTorchController().setBlockName("radio_torch_controller").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":rtty_controller");
|
||||||
radio_telex = new RadioTelex().setBlockName("radio_telex").setHardness(3F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":radio_telex");
|
radio_telex = new RadioTelex().setBlockName("radio_telex").setHardness(3F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":radio_telex");
|
||||||
|
radio_autocal = new RadioAUTOCAL().setBlockName("radio_autocal").setHardness(3F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||||
|
|
||||||
conveyor = new BlockConveyor().setBlockName("conveyor").setHardness(2.0F).setResistance(2.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":conveyor");
|
conveyor = new BlockConveyor().setBlockName("conveyor").setHardness(2.0F).setResistance(2.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":conveyor");
|
||||||
conveyor_express = new BlockConveyorExpress().setBlockName("conveyor_express").setHardness(2.0F).setResistance(2.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":conveyor_express");
|
conveyor_express = new BlockConveyorExpress().setBlockName("conveyor_express").setHardness(2.0F).setResistance(2.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":conveyor_express");
|
||||||
@ -3175,6 +3177,7 @@ public class ModBlocks {
|
|||||||
register(radio_torch_reader);
|
register(radio_torch_reader);
|
||||||
register(radio_torch_controller);
|
register(radio_torch_controller);
|
||||||
register(radio_telex);
|
register(radio_telex);
|
||||||
|
register(radio_autocal);
|
||||||
|
|
||||||
register(crane_extractor);
|
register(crane_extractor);
|
||||||
register(crane_inserter);
|
register(crane_inserter);
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import net.minecraftforge.common.util.ForgeDirection;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class MachineBigAssTank9000 extends BlockDummyable implements IPersistentInfoProvider {
|
public class MachineBigAssTank9000 extends BlockDummyable implements IPersistentInfoProvider {
|
||||||
|
|
||||||
public MachineBigAssTank9000(Material mat) {
|
public MachineBigAssTank9000(Material mat) {
|
||||||
|
|||||||
25
src/main/java/com/hbm/blocks/network/RadioAUTOCAL.java
Normal file
25
src/main/java/com/hbm/blocks/network/RadioAUTOCAL.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package com.hbm.blocks.network;
|
||||||
|
|
||||||
|
import com.hbm.blocks.machine.BlockMachineBase;
|
||||||
|
import com.hbm.tileentity.network.TileEntityRadioAUTOCAL;
|
||||||
|
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class RadioAUTOCAL extends BlockMachineBase {
|
||||||
|
|
||||||
|
public RadioAUTOCAL() {
|
||||||
|
super(Material.iron, 0);
|
||||||
|
this.rotatable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createNewTileEntity(World world, int meta) {
|
||||||
|
return new TileEntityRadioAUTOCAL();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getRenderType(){ return -1; }
|
||||||
|
@Override public boolean isOpaqueCube() { return false; }
|
||||||
|
@Override public boolean renderAsNormalBlock() { return false; }
|
||||||
|
}
|
||||||
@ -129,7 +129,7 @@ public class GeneralConfig {
|
|||||||
preferredOutputMod = CommonConfig.createConfigStringList(config,CATEGORY_GENERAL,"1.42_preferredOutputMod",
|
preferredOutputMod = CommonConfig.createConfigStringList(config,CATEGORY_GENERAL,"1.42_preferredOutputMod",
|
||||||
"The mod which is preferred as output when certain machines autogenerate recipes. Currently used for the shredder", new String[] {RefStrings.MODID});
|
"The mod which is preferred as output when certain machines autogenerate recipes. Currently used for the shredder", new String[] {RefStrings.MODID});
|
||||||
enableLoadScreenReplacement = config.get(CATEGORY_GENERAL, "1.43_enableLoadScreenReplacement", true, "Tries to replace the vanilla load screen with the 'tip of the day' one, may clash with other mods trying to do the same.").getBoolean(true);
|
enableLoadScreenReplacement = config.get(CATEGORY_GENERAL, "1.43_enableLoadScreenReplacement", true, "Tries to replace the vanilla load screen with the 'tip of the day' one, may clash with other mods trying to do the same.").getBoolean(true);
|
||||||
enableMachineGravity = config.get(CATEGORY_GENERAL, "1.44_enableMachineGravity", true, "Requires large large machines to have a proper foundation, or else they tilt and break. Independent from the 528 version of this config, which does the same, but only works with 528 enabled.").getBoolean(false);
|
enableMachineGravity = config.get(CATEGORY_GENERAL, "1.44_enableMachineGravity", false, "Requires large large machines to have a proper foundation, or else they tilt and break. Independent from the 528 version of this config, which does the same, but only works with 528 enabled.").getBoolean(false);
|
||||||
enableExpensiveMode = config.get(CATEGORY_GENERAL, "1.99_enableExpensiveMode", false, "It does what the name implies.").getBoolean(false);
|
enableExpensiveMode = config.get(CATEGORY_GENERAL, "1.99_enableExpensiveMode", false, "It does what the name implies.").getBoolean(false);
|
||||||
|
|
||||||
final String CATEGORY_528 = CommonConfig.CATEGORY_528;
|
final String CATEGORY_528 = CommonConfig.CATEGORY_528;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.hbm.inventory.gui;
|
package com.hbm.inventory.gui;
|
||||||
|
|
||||||
|
import com.hbm.util.Calculator;
|
||||||
import com.hbm.util.Tuple;
|
import com.hbm.util.Tuple;
|
||||||
|
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
@ -12,8 +13,6 @@ import java.math.MathContext;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public class GUICalculator extends GuiScreen {
|
public class GUICalculator extends GuiScreen {
|
||||||
private int xSize = 220;
|
private int xSize = 220;
|
||||||
@ -58,7 +57,7 @@ public class GUICalculator extends GuiScreen {
|
|||||||
selectedHist = -1;
|
selectedHist = -1;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
double result = evaluateExpression(input);
|
double result = Calculator.evaluateExpression(input);
|
||||||
history.addFirst(new Tuple.Pair<String,Double>(input, result));
|
history.addFirst(new Tuple.Pair<String,Double>(input, result));
|
||||||
if (history.size() > maxHistory) history.removeLast();
|
if (history.size() > maxHistory) history.removeLast();
|
||||||
String plainStringRepresentation = (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString();
|
String plainStringRepresentation = (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString();
|
||||||
@ -85,7 +84,7 @@ public class GUICalculator extends GuiScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
latestResult = Double.toString(evaluateExpression(input));
|
latestResult = Double.toString(Calculator.evaluateExpression(input));
|
||||||
} catch (Exception e) { latestResult = e.toString(); }
|
} catch (Exception e) { latestResult = e.toString(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,203 +115,4 @@ public class GUICalculator extends GuiScreen {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mathematically evaluates user-inputted strings<br>
|
|
||||||
* It is recommended to catch all exceptions when using this
|
|
||||||
*/
|
|
||||||
public static double evaluateExpression(String input) {
|
|
||||||
if (input.contains("^")) input = preEvaluatePower(input);
|
|
||||||
|
|
||||||
char[] tokens = input.toCharArray();
|
|
||||||
Stack<Double> values = new Stack<>();
|
|
||||||
Stack<String> operators = new Stack<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < tokens.length; i++) {
|
|
||||||
if (tokens[i] == ' ') continue;
|
|
||||||
|
|
||||||
if (tokens[i] >= '0' && tokens[i] <= '9' || tokens[i] == '.' || (tokens[i] == '-' && (i == 0 || "+-*/^(".contains(String.valueOf(tokens[i - 1]))))) {
|
|
||||||
StringBuilder buffer = new StringBuilder();
|
|
||||||
if (tokens[i] == '-') {
|
|
||||||
buffer.append('-'); // for negative numbers
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (i < tokens.length && (tokens[i] >= '0' && tokens[i] <= '9' || tokens[i] == '.')) buffer.append(tokens[i++]);
|
|
||||||
values.push(Double.parseDouble(buffer.toString()));
|
|
||||||
i--;
|
|
||||||
} else if (tokens[i] == '(') operators.push(Character.toString(tokens[i]));
|
|
||||||
else if (tokens[i] == ')') {
|
|
||||||
while (!operators.isEmpty() && operators.peek().charAt(0) != '(')
|
|
||||||
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
|
||||||
operators.pop();
|
|
||||||
if (!operators.isEmpty() && operators.peek().length() > 1)
|
|
||||||
values.push(evaluateFunction(operators.pop(), values.pop()));
|
|
||||||
} else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/' || tokens[i] == '^') {
|
|
||||||
while (!operators.isEmpty() && hasPrecedence(String.valueOf(tokens[i]), operators.peek()))
|
|
||||||
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
|
||||||
operators.push(Character.toString(tokens[i]));
|
|
||||||
} else if (tokens[i] == '!') {
|
|
||||||
values.push((double) factorial((int) Math.round(values.pop())));
|
|
||||||
}else if (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z') {
|
|
||||||
StringBuilder charBuffer = new StringBuilder();
|
|
||||||
while (i < tokens.length && (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z'))
|
|
||||||
charBuffer.append(tokens[i++]);
|
|
||||||
String string = charBuffer.toString();
|
|
||||||
if (string.equalsIgnoreCase("pi")) values.push(Math.PI);
|
|
||||||
else if (string.equalsIgnoreCase("e")) values.push(Math.E);
|
|
||||||
else operators.push(string.toLowerCase(Locale.ROOT));
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the expression is correctly formatted, no function is remaining
|
|
||||||
while (!operators.empty()) values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
|
||||||
|
|
||||||
return values.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double evaluateOperator(char operator, double x, double y) {
|
|
||||||
switch (operator) {
|
|
||||||
case '+': return y + x;
|
|
||||||
case '-': return y - x;
|
|
||||||
case '*': return y * x;
|
|
||||||
case '/': return y / x;
|
|
||||||
|
|
||||||
case '^': return Math.pow(y, x); // should not happen here, but oh well
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double evaluateFunction(String function, double x) {
|
|
||||||
switch (function) {
|
|
||||||
case "sqrt": return Math.sqrt(x);
|
|
||||||
|
|
||||||
case "sin": return Math.sin(x);
|
|
||||||
case "cos": return Math.cos(x);
|
|
||||||
case "tan": return Math.tan(x);
|
|
||||||
case "asin": return Math.asin(x);
|
|
||||||
case "acos": return Math.acos(x);
|
|
||||||
case "atan": return Math.atan(x);
|
|
||||||
|
|
||||||
case "log": return Math.log10(x);
|
|
||||||
case "ln": return Math.log(x);
|
|
||||||
|
|
||||||
case "ceil": return Math.ceil(x);
|
|
||||||
case "floor": return Math.floor(x);
|
|
||||||
case "round": return Math.round(x);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether {@code second} has precedence over {@code first} */
|
|
||||||
private static boolean hasPrecedence(String first, String second) {
|
|
||||||
if (second.length() > 1) return false;
|
|
||||||
|
|
||||||
char firstChar = first.charAt(0);
|
|
||||||
char secondChar = second.charAt(0);
|
|
||||||
|
|
||||||
if (secondChar == '(' || secondChar == ')') return false;
|
|
||||||
else return (firstChar != '*' && firstChar != '/' && firstChar != '^') || (secondChar != '+' && secondChar != '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the input with all powers evaluated */
|
|
||||||
private static String preEvaluatePower(String input) {
|
|
||||||
do {
|
|
||||||
int powerOperatorIndex = input.lastIndexOf('^');
|
|
||||||
|
|
||||||
// find base
|
|
||||||
boolean previousTokenIsParentheses = input.charAt(powerOperatorIndex - 1) == ')';
|
|
||||||
int parenthesesDepth = previousTokenIsParentheses ? 1 : 0;
|
|
||||||
int baseExpressionStart = previousTokenIsParentheses ? powerOperatorIndex - 2 : powerOperatorIndex - 1;
|
|
||||||
baseLoop:
|
|
||||||
for (; baseExpressionStart >= 0; baseExpressionStart--) { // search backwards
|
|
||||||
switch (input.charAt(baseExpressionStart)) {
|
|
||||||
case ')':
|
|
||||||
if (previousTokenIsParentheses) parenthesesDepth++;
|
|
||||||
else break baseLoop;
|
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
if (previousTokenIsParentheses && parenthesesDepth > 0) parenthesesDepth--;
|
|
||||||
else break baseLoop;
|
|
||||||
break;
|
|
||||||
case '+': case '-': case '*': case '/': case '^':
|
|
||||||
if (parenthesesDepth == 0) break baseLoop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
baseExpressionStart++; // go one token forward again
|
|
||||||
if (parenthesesDepth > 0) throw new IllegalArgumentException("Incomplete parentheses");
|
|
||||||
|
|
||||||
// find exponent
|
|
||||||
boolean nextTokenIsParentheses = input.charAt(powerOperatorIndex + 1) == '(';
|
|
||||||
parenthesesDepth = nextTokenIsParentheses ? 1 : 0;
|
|
||||||
int exponentExpressionEnd = nextTokenIsParentheses ? powerOperatorIndex + 2 : powerOperatorIndex + 1;
|
|
||||||
exponentLoop:
|
|
||||||
for (; exponentExpressionEnd < input.length(); exponentExpressionEnd++) {
|
|
||||||
switch (input.charAt(exponentExpressionEnd)) {
|
|
||||||
case '(':
|
|
||||||
if (nextTokenIsParentheses) parenthesesDepth++;
|
|
||||||
else break exponentLoop;
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
if (nextTokenIsParentheses && parenthesesDepth > 0) parenthesesDepth--;
|
|
||||||
else break exponentLoop;
|
|
||||||
break;
|
|
||||||
case '+': case '-': case '*': case '/': case '^':
|
|
||||||
if (parenthesesDepth == 0) break exponentLoop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parenthesesDepth > 0) throw new IllegalArgumentException("Incomplete parentheses");
|
|
||||||
|
|
||||||
double base = evaluateExpression(input.substring(baseExpressionStart, powerOperatorIndex));
|
|
||||||
double exponent = evaluateExpression(input.substring(powerOperatorIndex + 1, exponentExpressionEnd));
|
|
||||||
double result = Math.pow(base, exponent);
|
|
||||||
// use big decimal to avoid scientific notation messing with the calculation
|
|
||||||
input = input.substring(0, baseExpressionStart) + (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString() + input.substring(exponentExpressionEnd);
|
|
||||||
} while (input.contains("^"));
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Maybe switch the whole calculator to using BigInteger/BigDecimal?
|
|
||||||
// SplitRecursive algorithm
|
|
||||||
private static int factorial(int in) {
|
|
||||||
if (in < 0) throw new IllegalArgumentException("Factorial needs n >= 0");
|
|
||||||
if (in < 2) return 1;
|
|
||||||
int p = 1, r = 1;
|
|
||||||
factorialCurrentN = 1;
|
|
||||||
int h = 0, shift = 0, high = 1;
|
|
||||||
int log2n = log2(in);
|
|
||||||
while (h != in) {
|
|
||||||
shift += h;
|
|
||||||
h = in >> log2n--;
|
|
||||||
int len = high;
|
|
||||||
high = (h - 1) | 1;
|
|
||||||
len = (high - len) / 2;
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
p *= factorialProduct(len);
|
|
||||||
r *= p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r << shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int factorialCurrentN;
|
|
||||||
|
|
||||||
private static int factorialProduct(int in) {
|
|
||||||
int m = in / 2;
|
|
||||||
if (m == 0) return factorialCurrentN += 2;
|
|
||||||
if (in == 2) return (factorialCurrentN += 2) * (factorialCurrentN += 2);
|
|
||||||
return factorialProduct(in - m) * factorialProduct(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int log2(int in) {
|
|
||||||
int log = 0;
|
|
||||||
if((in & 0xffff0000) != 0) { in >>>= 16; log = 16; }
|
|
||||||
if(in >= 256) { in >>>= 8; log += 8; }
|
|
||||||
if(in >= 16) { in >>>= 4; log += 4; }
|
|
||||||
if(in >= 4) { in >>>= 2; log += 2; }
|
|
||||||
return log + (in >>> 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/main/java/com/hbm/module/IParse.java
Normal file
34
src/main/java/com/hbm/module/IParse.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package com.hbm.module;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public interface IParse {
|
||||||
|
|
||||||
|
public EnumStatementReturn eval(ParseContext ctx, String line);
|
||||||
|
|
||||||
|
public static class ParseContext {
|
||||||
|
public World world;
|
||||||
|
public NBTTagCompound variables;
|
||||||
|
public HashMap<String, Integer> jmp;
|
||||||
|
|
||||||
|
public Object buffer;
|
||||||
|
public int clockSpeed;
|
||||||
|
|
||||||
|
public ParseContext(World world, NBTTagCompound variables, HashMap<String, Integer> jmp) {
|
||||||
|
this.world = world;
|
||||||
|
this.variables = variables;
|
||||||
|
this.jmp = jmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum EnumStatementReturn {
|
||||||
|
OK,
|
||||||
|
UNRECOGNIZED_COMMAND,
|
||||||
|
PARAMETER_ERROR,
|
||||||
|
END_TICK,
|
||||||
|
UNDEFINED
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/com/hbm/module/ParseMSES1.java
Normal file
9
src/main/java/com/hbm/module/ParseMSES1.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.hbm.module;
|
||||||
|
|
||||||
|
public class ParseMSES1 implements IParse {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumStatementReturn eval(ParseContext ctx, String line) {
|
||||||
|
return EnumStatementReturn.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,11 @@
|
|||||||
package com.hbm.tileentity;
|
package com.hbm.tileentity;
|
||||||
|
|
||||||
import net.minecraftforge.fluids.FluidTank;
|
|
||||||
|
|
||||||
public abstract class TileEntityTickingBase extends TileEntityLoadedBase {
|
public abstract class TileEntityTickingBase extends TileEntityLoadedBase {
|
||||||
|
|
||||||
public TileEntityTickingBase() { }
|
public TileEntityTickingBase() { }
|
||||||
|
|
||||||
public abstract String getInventoryName();
|
public abstract String getInventoryName();
|
||||||
|
|
||||||
public int getGaugeScaled(int i, FluidTank tank) {
|
|
||||||
return tank.getFluidAmount() * i / tank.getCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
//abstracting this method forces child classes to implement it
|
//abstracting this method forces child classes to implement it
|
||||||
//so i don't have to remember the fucking method name
|
//so i don't have to remember the fucking method name
|
||||||
//was it update? onUpdate? updateTile? did it have any args?
|
//was it update? onUpdate? updateTile? did it have any args?
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import cpw.mods.fml.relauncher.Side;
|
|||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
import net.minecraft.util.AxisAlignedBB;
|
import net.minecraft.util.AxisAlignedBB;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class TileEntityMachineBAT9000 extends TileEntityBarrel {
|
public class TileEntityMachineBAT9000 extends TileEntityBarrel {
|
||||||
|
|
||||||
public TileEntityMachineBAT9000() {
|
public TileEntityMachineBAT9000() {
|
||||||
|
|||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.hbm.tileentity.network;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.hbm.tileentity.TileEntityTickingBase;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
public class TileEntityRadioAUTOCAL extends TileEntityTickingBase {
|
||||||
|
|
||||||
|
public boolean isOn = false;
|
||||||
|
|
||||||
|
public Object buffer;
|
||||||
|
public NBTTagCompound variables;
|
||||||
|
public String[] script;
|
||||||
|
public HashMap<String, Integer> jmp = new HashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInventoryName() {
|
||||||
|
return "container.autocal";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntity() {
|
||||||
|
|
||||||
|
if(!worldObj.isRemote) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(ByteBuf buf) {
|
||||||
|
super.serialize(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserialize(ByteBuf buf) {
|
||||||
|
super.deserialize(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
208
src/main/java/com/hbm/util/Calculator.java
Normal file
208
src/main/java/com/hbm/util/Calculator.java
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
package com.hbm.util;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class Calculator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mathematically evaluates user-inputted strings<br>
|
||||||
|
* It is recommended to catch all exceptions when using this
|
||||||
|
*/
|
||||||
|
public static double evaluateExpression(String input) {
|
||||||
|
if (input.contains("^")) input = preEvaluatePower(input);
|
||||||
|
|
||||||
|
char[] tokens = input.toCharArray();
|
||||||
|
Stack<Double> values = new Stack<>();
|
||||||
|
Stack<String> operators = new Stack<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < tokens.length; i++) {
|
||||||
|
if (tokens[i] == ' ') continue;
|
||||||
|
|
||||||
|
if (tokens[i] >= '0' && tokens[i] <= '9' || tokens[i] == '.' || (tokens[i] == '-' && (i == 0 || "+-*/^(".contains(String.valueOf(tokens[i - 1]))))) {
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
if (tokens[i] == '-') {
|
||||||
|
buffer.append('-'); // for negative numbers
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (i < tokens.length && (tokens[i] >= '0' && tokens[i] <= '9' || tokens[i] == '.')) buffer.append(tokens[i++]);
|
||||||
|
values.push(Double.parseDouble(buffer.toString()));
|
||||||
|
i--;
|
||||||
|
} else if (tokens[i] == '(') operators.push(Character.toString(tokens[i]));
|
||||||
|
else if (tokens[i] == ')') {
|
||||||
|
while (!operators.isEmpty() && operators.peek().charAt(0) != '(')
|
||||||
|
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
||||||
|
operators.pop();
|
||||||
|
if (!operators.isEmpty() && operators.peek().length() > 1)
|
||||||
|
values.push(evaluateFunction(operators.pop(), values.pop()));
|
||||||
|
} else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/' || tokens[i] == '^') {
|
||||||
|
while (!operators.isEmpty() && hasPrecedence(String.valueOf(tokens[i]), operators.peek()))
|
||||||
|
values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
||||||
|
operators.push(Character.toString(tokens[i]));
|
||||||
|
} else if (tokens[i] == '!') {
|
||||||
|
values.push((double) factorial((int) Math.round(values.pop())));
|
||||||
|
}else if (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z') {
|
||||||
|
StringBuilder charBuffer = new StringBuilder();
|
||||||
|
while (i < tokens.length && (tokens[i] >= 'A' && tokens[i] <= 'Z' || tokens[i] >= 'a' && tokens[i] <= 'z'))
|
||||||
|
charBuffer.append(tokens[i++]);
|
||||||
|
String string = charBuffer.toString();
|
||||||
|
if (string.equalsIgnoreCase("pi")) values.push(Math.PI);
|
||||||
|
else if (string.equalsIgnoreCase("e")) values.push(Math.E);
|
||||||
|
else operators.push(string.toLowerCase(Locale.ROOT));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the expression is correctly formatted, no function is remaining
|
||||||
|
while (!operators.empty()) values.push(evaluateOperator(operators.pop().charAt(0), values.pop(), values.pop()));
|
||||||
|
|
||||||
|
return values.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double evaluateOperator(char operator, double x, double y) {
|
||||||
|
switch (operator) {
|
||||||
|
case '+': return y + x;
|
||||||
|
case '-': return y - x;
|
||||||
|
case '*': return y * x;
|
||||||
|
case '/': return y / x;
|
||||||
|
|
||||||
|
case '^': return Math.pow(y, x); // should not happen here, but oh well
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double evaluateFunction(String function, double x) {
|
||||||
|
switch (function) {
|
||||||
|
case "sqrt": return Math.sqrt(x);
|
||||||
|
|
||||||
|
case "sin": return Math.sin(x);
|
||||||
|
case "cos": return Math.cos(x);
|
||||||
|
case "tan": return Math.tan(x);
|
||||||
|
case "asin": return Math.asin(x);
|
||||||
|
case "acos": return Math.acos(x);
|
||||||
|
case "atan": return Math.atan(x);
|
||||||
|
|
||||||
|
case "log": return Math.log10(x);
|
||||||
|
case "ln": return Math.log(x);
|
||||||
|
|
||||||
|
case "ceil": return Math.ceil(x);
|
||||||
|
case "floor": return Math.floor(x);
|
||||||
|
case "round": return Math.round(x);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether {@code second} has precedence over {@code first} */
|
||||||
|
private static boolean hasPrecedence(String first, String second) {
|
||||||
|
if (second.length() > 1) return false;
|
||||||
|
|
||||||
|
char firstChar = first.charAt(0);
|
||||||
|
char secondChar = second.charAt(0);
|
||||||
|
|
||||||
|
if (secondChar == '(' || secondChar == ')') return false;
|
||||||
|
else return (firstChar != '*' && firstChar != '/' && firstChar != '^') || (secondChar != '+' && secondChar != '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the input with all powers evaluated */
|
||||||
|
private static String preEvaluatePower(String input) {
|
||||||
|
do {
|
||||||
|
int powerOperatorIndex = input.lastIndexOf('^');
|
||||||
|
|
||||||
|
// find base
|
||||||
|
boolean previousTokenIsParentheses = input.charAt(powerOperatorIndex - 1) == ')';
|
||||||
|
int parenthesesDepth = previousTokenIsParentheses ? 1 : 0;
|
||||||
|
int baseExpressionStart = previousTokenIsParentheses ? powerOperatorIndex - 2 : powerOperatorIndex - 1;
|
||||||
|
baseLoop:
|
||||||
|
for (; baseExpressionStart >= 0; baseExpressionStart--) { // search backwards
|
||||||
|
switch (input.charAt(baseExpressionStart)) {
|
||||||
|
case ')':
|
||||||
|
if (previousTokenIsParentheses) parenthesesDepth++;
|
||||||
|
else break baseLoop;
|
||||||
|
break;
|
||||||
|
case '(':
|
||||||
|
if (previousTokenIsParentheses && parenthesesDepth > 0) parenthesesDepth--;
|
||||||
|
else break baseLoop;
|
||||||
|
break;
|
||||||
|
case '+': case '-': case '*': case '/': case '^':
|
||||||
|
if (parenthesesDepth == 0) break baseLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
baseExpressionStart++; // go one token forward again
|
||||||
|
if (parenthesesDepth > 0) throw new IllegalArgumentException("Incomplete parentheses");
|
||||||
|
|
||||||
|
// find exponent
|
||||||
|
boolean nextTokenIsParentheses = input.charAt(powerOperatorIndex + 1) == '(';
|
||||||
|
parenthesesDepth = nextTokenIsParentheses ? 1 : 0;
|
||||||
|
int exponentExpressionEnd = nextTokenIsParentheses ? powerOperatorIndex + 2 : powerOperatorIndex + 1;
|
||||||
|
exponentLoop:
|
||||||
|
for (; exponentExpressionEnd < input.length(); exponentExpressionEnd++) {
|
||||||
|
switch (input.charAt(exponentExpressionEnd)) {
|
||||||
|
case '(':
|
||||||
|
if (nextTokenIsParentheses) parenthesesDepth++;
|
||||||
|
else break exponentLoop;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
if (nextTokenIsParentheses && parenthesesDepth > 0) parenthesesDepth--;
|
||||||
|
else break exponentLoop;
|
||||||
|
break;
|
||||||
|
case '+': case '-': case '*': case '/': case '^':
|
||||||
|
if (parenthesesDepth == 0) break exponentLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parenthesesDepth > 0) throw new IllegalArgumentException("Incomplete parentheses");
|
||||||
|
|
||||||
|
double base = evaluateExpression(input.substring(baseExpressionStart, powerOperatorIndex));
|
||||||
|
double exponent = evaluateExpression(input.substring(powerOperatorIndex + 1, exponentExpressionEnd));
|
||||||
|
double result = Math.pow(base, exponent);
|
||||||
|
// use big decimal to avoid scientific notation messing with the calculation
|
||||||
|
input = input.substring(0, baseExpressionStart) + (new BigDecimal(result, MathContext.DECIMAL64)).toPlainString() + input.substring(exponentExpressionEnd);
|
||||||
|
} while (input.contains("^"));
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Maybe switch the whole calculator to using BigInteger/BigDecimal?
|
||||||
|
// SplitRecursive algorithm
|
||||||
|
private static int factorial(int in) {
|
||||||
|
if (in < 0) throw new IllegalArgumentException("Factorial needs n >= 0");
|
||||||
|
if (in < 2) return 1;
|
||||||
|
int p = 1, r = 1;
|
||||||
|
factorialCurrentN = 1;
|
||||||
|
int h = 0, shift = 0, high = 1;
|
||||||
|
int log2n = log2(in);
|
||||||
|
while (h != in) {
|
||||||
|
shift += h;
|
||||||
|
h = in >> log2n--;
|
||||||
|
int len = high;
|
||||||
|
high = (h - 1) | 1;
|
||||||
|
len = (high - len) / 2;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
p *= factorialProduct(len);
|
||||||
|
r *= p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r << shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int factorialCurrentN;
|
||||||
|
|
||||||
|
private static int factorialProduct(int in) {
|
||||||
|
int m = in / 2;
|
||||||
|
if (m == 0) return factorialCurrentN += 2;
|
||||||
|
if (in == 2) return (factorialCurrentN += 2) * (factorialCurrentN += 2);
|
||||||
|
return factorialProduct(in - m) * factorialProduct(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int log2(int in) {
|
||||||
|
int log = 0;
|
||||||
|
if((in & 0xffff0000) != 0) { in >>>= 16; log = 16; }
|
||||||
|
if(in >= 256) { in >>>= 8; log += 8; }
|
||||||
|
if(in >= 16) { in >>>= 4; log += 4; }
|
||||||
|
if(in >= 4) { in >>>= 2; log += 2; }
|
||||||
|
return log + (in >>> 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -223,6 +223,7 @@ container.bat9000=Big-Ass Tank 9000
|
|||||||
container.battery=Energiespeicher
|
container.battery=Energiespeicher
|
||||||
container.batteryREDD=FEnSU
|
container.batteryREDD=FEnSU
|
||||||
container.batterySocket=Batteriesockel
|
container.batterySocket=Batteriesockel
|
||||||
|
container.bigAssTank=Big-Ass Tank
|
||||||
container.bombMulti=Mehrzweckbombe
|
container.bombMulti=Mehrzweckbombe
|
||||||
container.casingBag=Hülsentasche
|
container.casingBag=Hülsentasche
|
||||||
container.catalyticReformer=Katalytischer Reformer
|
container.catalyticReformer=Katalytischer Reformer
|
||||||
@ -4414,6 +4415,7 @@ tile.machine_battery_potato.name=Kartoffelbatterieblock (LEGACY)
|
|||||||
tile.machine_battery_redd.name=FEnSU
|
tile.machine_battery_redd.name=FEnSU
|
||||||
tile.machine_battery_socket.name=Batteriesockel
|
tile.machine_battery_socket.name=Batteriesockel
|
||||||
tile.machine_battery_socket.desc=Erlaubt es, Batterien direkt mit$dem Stromnetz zu verbinden.$Verhält sich wie ein Kabel, alle$Verbindungen sind im selben Netzwek.
|
tile.machine_battery_socket.desc=Erlaubt es, Batterien direkt mit$dem Stromnetz zu verbinden.$Verhält sich wie ein Kabel, alle$Verbindungen sind im selben Netzwek.
|
||||||
|
tile.machine_bigasstank.name=Big-Ass Tank
|
||||||
tile.machine_boiler.name=Boiler
|
tile.machine_boiler.name=Boiler
|
||||||
tile.machine_boiler.desc=Großer Boiler zum Verdampfen von Wasser oder$Erhitzen von Öl. Benötigt externe Hitzequelle.$Wärmestransferrate: ΔT*0.1 TU/t
|
tile.machine_boiler.desc=Großer Boiler zum Verdampfen von Wasser oder$Erhitzen von Öl. Benötigt externe Hitzequelle.$Wärmestransferrate: ΔT*0.1 TU/t
|
||||||
tile.machine_boiler_electric_off.name=Elektrischer Ölwärmer
|
tile.machine_boiler_electric_off.name=Elektrischer Ölwärmer
|
||||||
|
|||||||
@ -624,6 +624,7 @@ container.bat9000=Big-Ass Tank 9000
|
|||||||
container.battery=Energy Storage
|
container.battery=Energy Storage
|
||||||
container.batteryREDD=FEnSU
|
container.batteryREDD=FEnSU
|
||||||
container.batterySocket=Battery Socket
|
container.batterySocket=Battery Socket
|
||||||
|
container.bigAssTank=Big-Ass Tank
|
||||||
container.bombMulti=Multi Purpose Bomb
|
container.bombMulti=Multi Purpose Bomb
|
||||||
container.casingBag=Bullet Casing Bag
|
container.casingBag=Bullet Casing Bag
|
||||||
container.catalyticReformer=Catalytic Reformer
|
container.catalyticReformer=Catalytic Reformer
|
||||||
@ -5662,6 +5663,7 @@ tile.machine_battery_potato.name=Potato Battery Block (LEGACY)
|
|||||||
tile.machine_battery_redd.name=FEnSU
|
tile.machine_battery_redd.name=FEnSU
|
||||||
tile.machine_battery_socket.name=Battery Socket
|
tile.machine_battery_socket.name=Battery Socket
|
||||||
tile.machine_battery_socket.desc=Allows battery items to be connected$to the power grid directly.$Acts as a cable, all ports are connected$to the same network.
|
tile.machine_battery_socket.desc=Allows battery items to be connected$to the power grid directly.$Acts as a cable, all ports are connected$to the same network.
|
||||||
|
tile.machine_bigasstank.name=Big-Ass Tank
|
||||||
tile.machine_boiler.name=Boiler
|
tile.machine_boiler.name=Boiler
|
||||||
tile.machine_boiler.desc=Large boiler that can boil water or heat up oil.$Requires external heat source.$Heat transfer rate: ΔT*0.1 TU/t
|
tile.machine_boiler.desc=Large boiler that can boil water or heat up oil.$Requires external heat source.$Heat transfer rate: ΔT*0.1 TU/t
|
||||||
tile.machine_boiler_electric_off.name=Electric Oil Heater
|
tile.machine_boiler_electric_off.name=Electric Oil Heater
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user