diff --git a/docs/scarpet/language/Math.md b/docs/scarpet/language/Math.md index 10cccaf0..afb89987 100644 --- a/docs/scarpet/language/Math.md +++ b/docs/scarpet/language/Math.md @@ -6,11 +6,12 @@ There is bunch of them - they require a number and spit out a number, doing what ### `fact(n)` -Factorial of a number, a.k.a `n!`, just not in `scarpet`. Gets big... quick... +Factorial of a number, a.k.a `n!`, just not in `scarpet`. Gets big... quick... Therefore, values larger +than `fact(20)` will not return the exact value, but a value with 'double-float' precision. ### `sqrt(n)` -Square root. For other fancy roots, use `^`, math and yo noggin. Imagine square roots on a tree... +Square root (not 'a squirt') of a number. For other fancy roots, use `^`, math and yo noggin. Imagine square roots on a tree... ### `abs(n)` diff --git a/src/main/java/carpet/commands/SpawnCommand.java b/src/main/java/carpet/commands/SpawnCommand.java index 68c17e63..6b7e5ed8 100644 --- a/src/main/java/carpet/commands/SpawnCommand.java +++ b/src/main/java/carpet/commands/SpawnCommand.java @@ -22,6 +22,7 @@ import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockPos; import java.util.Arrays; +import java.util.Locale; import java.util.stream.Collectors; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; @@ -111,7 +112,7 @@ public class SpawnCommand { throw new SimpleCommandExceptionType(Messenger.c("r Wrong mob type: "+string+" should be "+ Arrays.stream(SpawnGroup.values()).map(SpawnGroup::getName).collect(Collectors.joining(", ")))).create(); } - return SpawnGroup.valueOf(string.toUpperCase()); + return SpawnGroup.byName(string.toLowerCase(Locale.ROOT)); } diff --git a/src/main/java/carpet/commands/TestCommand.java b/src/main/java/carpet/commands/TestCommand.java index 63cace57..6f097376 100644 --- a/src/main/java/carpet/commands/TestCommand.java +++ b/src/main/java/carpet/commands/TestCommand.java @@ -15,7 +15,7 @@ public class TestCommand { public static void register(CommandDispatcher dispatcher) { - dispatcher.register(literal("test"). + dispatcher.register(literal("testcarpet"). then(literal("dump"). executes((c) -> CarpetServer.settingsManager.printAllRulesToLog(null)). then(argument("category", word()). diff --git a/src/main/java/carpet/fakes/RecipeManagerInterface.java b/src/main/java/carpet/fakes/RecipeManagerInterface.java index d61db8a1..1078b24b 100644 --- a/src/main/java/carpet/fakes/RecipeManagerInterface.java +++ b/src/main/java/carpet/fakes/RecipeManagerInterface.java @@ -13,5 +13,5 @@ public interface RecipeManagerInterface * Gets all the recipes for a given item. Also used for {@link carpet.helpers.HopperCounter#guessColor} to guess the * colour of an item to display it prettily */ - List> getAllMatching(RecipeType type, Identifier output); + List> getAllMatching(RecipeType type, Identifier output); } diff --git a/src/main/java/carpet/mixins/RecipeManager_scarpetMixin.java b/src/main/java/carpet/mixins/RecipeManager_scarpetMixin.java index c31d4648..167ca616 100644 --- a/src/main/java/carpet/mixins/RecipeManager_scarpetMixin.java +++ b/src/main/java/carpet/mixins/RecipeManager_scarpetMixin.java @@ -22,9 +22,11 @@ public class RecipeManager_scarpetMixin implements RecipeManagerInterface @Shadow private Map, Map>> recipes; @Override - public List> getAllMatching(RecipeType type, Identifier output) + public List> getAllMatching(RecipeType type, Identifier output) { Map> typeRecipes = recipes.get(type); + // happens when mods add recipe to the registry without updating recipe manager + if (typeRecipes == null) return Collections.emptyList(); if (typeRecipes.containsKey(output)) return Collections.singletonList(typeRecipes.get(output)); return Lists.newArrayList(typeRecipes.values().stream().filter( r -> Registry.ITEM.getId(r.getOutput().getItem()).equals(output)).collect(Collectors.toList())); diff --git a/src/main/java/carpet/patches/EntityPlayerMPFake.java b/src/main/java/carpet/patches/EntityPlayerMPFake.java index 4041232b..1282ea12 100644 --- a/src/main/java/carpet/patches/EntityPlayerMPFake.java +++ b/src/main/java/carpet/patches/EntityPlayerMPFake.java @@ -135,8 +135,18 @@ public class EntityPlayerMPFake extends ServerPlayerEntity this.getServerWorld().getChunkManager().updatePosition(this); onTeleportationDone(); //<- causes hard crash but would need to be done to enable portals // not as of 1.17 } - super.tick(); - this.playerTick(); + try + { + super.tick(); + this.playerTick(); + } + catch (NullPointerException ignored) + { + // happens with that paper port thingy - not sure what that would fix, but hey + // the game not gonna crash violently. + } + + } private void shakeOff() diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index e4553619..ac4b666f 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -1162,20 +1162,28 @@ public class Expression for (Map.Entry pair : functionalEquivalence.entrySet()) { String operator = pair.getKey(); String function = pair.getValue(); - if (symbol.equals(operator) || symbol.equals(function)) { - List newargs = new ArrayList<>(); - boolean contracted = false; - for (ExpressionNode arg : node.args) { - String argsymbol = arg.token.surface; // child is unoptimized and also same class - if ((argsymbol.equals(operator) || argsymbol.equals(function)) && (!(arg.op instanceof LazyValue.ContextFreeLazyValue))) { - newargs.addAll(arg.args); - contracted = true; - } else { - newargs.add(arg); - } - } - if (contracted) { + if ((symbol.equals(operator) || symbol.equals(function)) && node.args.size() > 0) + { + boolean leftOptimizable = operators.get(operator).isLeftAssoc(); + ExpressionNode optimizedChild = node.args.get(leftOptimizable?0:(node.args.size()-1)); + String type = optimizedChild.token.surface; + if ((type.equals(operator) || type.equals(function)) && (!(optimizedChild.op instanceof LazyValue.ContextFreeLazyValue))) + { optimized = true; + List newargs = new ArrayList<>(); + if (leftOptimizable) + { + newargs.addAll(optimizedChild.args); + for (int i = 1; i < node.args.size(); i++) + newargs.add(node.args.get(i)); + } + else + { + for (int i = 0; i < node.args.size()-1; i++) + newargs.add(node.args.get(i)); + newargs.addAll(optimizedChild.args); + } + if (CarpetSettings.scriptsDebugging) CarpetScriptServer.LOG.info(" - " + symbol + "(" + node.args.size() + ") => " + function + "(" + newargs.size() + ") at line " + (node.token.lineno + 1) + ", node depth " + indent); node.token.morph(Tokenizer.Token.TokenType.FUNCTION, function); diff --git a/src/main/java/carpet/script/api/Inventories.java b/src/main/java/carpet/script/api/Inventories.java index 41a7ed73..e7ccb2a8 100644 --- a/src/main/java/carpet/script/api/Inventories.java +++ b/src/main/java/carpet/script/api/Inventories.java @@ -93,7 +93,7 @@ public class Inventories { CarpetContext cc = (CarpetContext)c; if (lv.size() < 1) throw new InternalExpressionException("'recipe_data' requires at least one argument"); String recipeName = lv.get(0).getString(); - RecipeType type = RecipeType.CRAFTING; + RecipeType type = RecipeType.CRAFTING; if (lv.size() > 1) { String recipeType = lv.get(1).getString(); diff --git a/src/main/java/carpet/script/language/Arithmetic.java b/src/main/java/carpet/script/language/Arithmetic.java index e5b543f9..46f308e6 100644 --- a/src/main/java/carpet/script/language/Arithmetic.java +++ b/src/main/java/carpet/script/language/Arithmetic.java @@ -20,12 +20,23 @@ public class Arithmetic { expression.addUnaryFunction("fact", (v) -> { long number = NumericValue.asNumber(v).getLong(); - long factorial = 1; + if (number < 21) + { + long factorial = 1; + for (int i = 1; i <= number; i++) + { + factorial = factorial * i; + } + return new NumericValue(factorial); + } + // values over 21 will exceed long limits + double factorial = 1.0; for (int i = 1; i <= number; i++) { factorial = factorial * i; } return new NumericValue(factorial); + }); expression.addMathematicalUnaryFunction("sin", (d) -> Math.sin(Math.toRadians(d))); expression.addMathematicalUnaryFunction("cos", (d) -> Math.cos(Math.toRadians(d)));