Merge branch '1.17' of https://github.com/DimensionalDevelopment/DimDoors into 1.17
This commit is contained in:
commit
0005dfec3c
9 changed files with 148 additions and 71 deletions
|
@ -122,7 +122,7 @@ public class DetachedRiftBlockEntity extends RiftBlockEntity {
|
||||||
@Override
|
@Override
|
||||||
public boolean receiveEntity(Entity entity, Vec3d relativePos, EulerAngle relativeAngle, Vec3d velocity) {
|
public boolean receiveEntity(Entity entity, Vec3d relativePos, EulerAngle relativeAngle, Vec3d velocity) {
|
||||||
if (this.world instanceof ServerWorld)
|
if (this.world instanceof ServerWorld)
|
||||||
TeleportUtil.teleport(entity, this.world, this.pos, relativeAngle);
|
TeleportUtil.teleport(entity, this.world, this.pos, relativeAngle, velocity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,6 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
||||||
if (block instanceof CoordinateTransformerBlock) {
|
if (block instanceof CoordinateTransformerBlock) {
|
||||||
CoordinateTransformerBlock transformer = (CoordinateTransformerBlock) block;
|
CoordinateTransformerBlock transformer = (CoordinateTransformerBlock) block;
|
||||||
|
|
||||||
System.out.println("{yaw: " + relativeAngle.getYaw() + "; pitch: " + relativeAngle.getPitch() + "; roll: " + relativeAngle.getRoll() + "}");
|
|
||||||
|
|
||||||
if (transformer.isExitFlipped()) {
|
if (transformer.isExitFlipped()) {
|
||||||
TransformationMatrix3d flipper = TransformationMatrix3d.builder().rotateY(Math.PI).build();
|
TransformationMatrix3d flipper = TransformationMatrix3d.builder().rotateY(Math.PI).build();
|
||||||
|
|
||||||
|
@ -66,8 +64,6 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
||||||
relativeVelocity = flipper.transform(relativeVelocity);
|
relativeVelocity = flipper.transform(relativeVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("{yaw: " + relativeAngle.getYaw() + "; pitch: " + relativeAngle.getPitch() + "; roll: " + relativeAngle.getRoll() + "}");
|
|
||||||
|
|
||||||
relativePos = relativePos.add(new Vec3d(0, 0, 1).multiply(0.6)); // TODO: skip this for Immersive Portals
|
relativePos = relativePos.add(new Vec3d(0, 0, 1).multiply(0.6)); // TODO: skip this for Immersive Portals
|
||||||
|
|
||||||
TransformationMatrix3d.TransformationMatrix3dBuilder transformationBuilder = transformer.transformationBuilder(state, this.getPos());
|
TransformationMatrix3d.TransformationMatrix3dBuilder transformationBuilder = transformer.transformationBuilder(state, this.getPos());
|
||||||
|
@ -77,11 +73,10 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
||||||
relativeVelocity = transformer.rotateOut(rotatorBuilder, relativeVelocity);
|
relativeVelocity = transformer.rotateOut(rotatorBuilder, relativeVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
TeleportUtil.teleport(entity, this.world, targetPos, relativeAngle);
|
entity = TeleportUtil.teleport(entity, this.world, targetPos, relativeAngle, relativeVelocity);
|
||||||
entity.setVelocity(relativeVelocity);
|
|
||||||
if (entity instanceof ServerPlayerEntity) {
|
if (entity instanceof ServerPlayerEntity) {
|
||||||
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
||||||
player.networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(player));
|
player.networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(player.getId(), relativeVelocity));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class DimTeleportCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int teleport(Entity entity, ServerWorld dimension, Vec3d pos) {
|
private static int teleport(Entity entity, ServerWorld dimension, Vec3d pos) {
|
||||||
TeleportUtil.teleport(entity, dimension, pos, MathUtil.entityEulerAngle(entity));
|
TeleportUtil.teleport(entity, dimension, pos, MathUtil.entityEulerAngle(entity), entity.getVelocity());
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class EscapeTarget extends VirtualTarget implements EntityTarget { // TOD
|
||||||
Location destLoc = DimensionalRegistry.getRiftRegistry().getOverworldRift(uuid);
|
Location destLoc = DimensionalRegistry.getRiftRegistry().getOverworldRift(uuid);
|
||||||
if (destLoc != null && destLoc.getBlockEntity() instanceof RiftBlockEntity || this.canEscapeLimbo) {
|
if (destLoc != null && destLoc.getBlockEntity() instanceof RiftBlockEntity || this.canEscapeLimbo) {
|
||||||
Location location = VirtualLocation.fromLocation(new Location((ServerWorld) entity.world, entity.getBlockPos())).projectToWorld(false);
|
Location location = VirtualLocation.fromLocation(new Location((ServerWorld) entity.world, entity.getBlockPos())).projectToWorld(false);
|
||||||
TeleportUtil.teleport(entity, location.getWorld(), location.getBlockPos(), relativeAngle);
|
TeleportUtil.teleport(entity, location.getWorld(), location.getBlockPos(), relativeAngle, relativeVelocity);
|
||||||
} else {
|
} else {
|
||||||
if (destLoc == null) {
|
if (destLoc == null) {
|
||||||
chat(entity, new TranslatableText("rifts.destinations.escape.did_not_use_rift"));
|
chat(entity, new TranslatableText("rifts.destinations.escape.did_not_use_rift"));
|
||||||
|
@ -56,7 +56,7 @@ public class EscapeTarget extends VirtualTarget implements EntityTarget { // TOD
|
||||||
chat(entity, new TranslatableText("rifts.destinations.escape.rift_has_closed"));
|
chat(entity, new TranslatableText("rifts.destinations.escape.rift_has_closed"));
|
||||||
}
|
}
|
||||||
if (ModDimensions.LIMBO_DIMENSION != null) {
|
if (ModDimensions.LIMBO_DIMENSION != null) {
|
||||||
TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, new BlockPos(this.location.getX(), this.location.getY(), this.location.getZ()), relativeAngle);
|
TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, new BlockPos(this.location.getX(), this.location.getY(), this.location.getZ()), relativeAngle, relativeVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class LimboTarget extends VirtualTarget implements EntityTarget {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean receiveEntity(Entity entity, Vec3d relativePos, EulerAngle relativeAngle, Vec3d relativeVelocity) {
|
public boolean receiveEntity(Entity entity, Vec3d relativePos, EulerAngle relativeAngle, Vec3d relativeVelocity) {
|
||||||
TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, entity.getPos(), relativeAngle);
|
TeleportUtil.teleport(entity, ModDimensions.LIMBO_DIMENSION, entity.getPos(), relativeAngle, relativeVelocity);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ public abstract class VirtualTarget implements Target {
|
||||||
VirtualTargetType<PrivatePocketExitTarget> PRIVATE_POCKET_EXIT = register("dimdoors:private_pocket_exit", a -> new PrivatePocketExitTarget(), a -> new CompoundTag(), PrivatePocketExitTarget.COLOR);
|
VirtualTargetType<PrivatePocketExitTarget> PRIVATE_POCKET_EXIT = register("dimdoors:private_pocket_exit", a -> new PrivatePocketExitTarget(), a -> new CompoundTag(), PrivatePocketExitTarget.COLOR);
|
||||||
VirtualTargetType<RelativeReference> RELATIVE = register("dimdoors:relative", RelativeReference::fromTag, RelativeReference::toTag, VirtualTarget.COLOR);
|
VirtualTargetType<RelativeReference> RELATIVE = register("dimdoors:relative", RelativeReference::fromTag, RelativeReference::toTag, VirtualTarget.COLOR);
|
||||||
VirtualTargetType<IdMarker> ID_MARKER = register("dimdoors:id_marker", IdMarker::fromTag, IdMarker::toTag, VirtualTarget.COLOR);
|
VirtualTargetType<IdMarker> ID_MARKER = register("dimdoors:id_marker", IdMarker::fromTag, IdMarker::toTag, VirtualTarget.COLOR);
|
||||||
VirtualTargetType<UnstableTarget> UNSTABLE = register("dimdoors:unstable", tag -> new UnstableTarget(), t -> new CompoundTag(), VirtualTarget.COLOR);
|
//VirtualTargetType<UnstableTarget> UNSTABLE = register("dimdoors:unstable", tag -> new UnstableTarget(), t -> new CompoundTag(), VirtualTarget.COLOR);
|
||||||
VirtualTargetType<NoneTarget> NONE = register("dimdoors:none", tag -> NoneTarget.INSTANCE, i -> new CompoundTag(), COLOR);
|
VirtualTargetType<NoneTarget> NONE = register("dimdoors:none", tag -> NoneTarget.INSTANCE, i -> new CompoundTag(), COLOR);
|
||||||
|
|
||||||
T fromTag(CompoundTag tag);
|
T fromTag(CompoundTag tag);
|
||||||
|
|
|
@ -18,49 +18,48 @@ import org.dimdev.dimdoors.util.math.MathUtil;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public final class TeleportUtil {
|
public final class TeleportUtil {
|
||||||
public static void teleport(Entity entity, World world, BlockPos pos, float yaw) {
|
public static <E extends Entity> E teleport(E entity, World world, BlockPos pos, float yaw) {
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
||||||
}
|
}
|
||||||
|
|
||||||
teleport(entity, world, Vec3d.ofBottomCenter(pos), yaw);
|
return teleport(entity, world, Vec3d.ofBottomCenter(pos), yaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleport(Entity entity, World world, Vec3d pos, float yaw) {
|
public static <E extends Entity> E teleport(E entity, World world, Vec3d pos, float yaw) {
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
||||||
}
|
}
|
||||||
|
|
||||||
FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, entity.getVelocity(), yaw, entity.getPitch(1.0F)));
|
return FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, entity.getVelocity(), yaw, entity.getPitch(1.0F)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleport(Entity entity, World world, Vec3d pos, EulerAngle angle) {
|
public static <E extends Entity> E teleport(E entity, World world, Vec3d pos, EulerAngle angle, Vec3d velocity) {
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
||||||
}
|
}
|
||||||
|
|
||||||
FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, entity.getVelocity(), angle.getYaw(), angle.getPitch()));
|
return FabricDimensions.teleport(entity, (ServerWorld) world, new TeleportTarget(pos, velocity, angle.getYaw(), angle.getPitch()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleport(Entity entity, World world, BlockPos pos, EulerAngle angle) {
|
public static <E extends Entity> E teleport(E entity, World world, BlockPos pos, EulerAngle angle, Vec3d velocity) {
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
throw new UnsupportedOperationException("Only supported on ServerWorld");
|
||||||
}
|
}
|
||||||
|
|
||||||
teleport(entity, world, Vec3d.ofBottomCenter(pos), angle);
|
return teleport(entity, world, Vec3d.ofBottomCenter(pos), angle, velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleport(ServerPlayerEntity player, Location location) {
|
public static ServerPlayerEntity teleport(ServerPlayerEntity player, Location location) {
|
||||||
teleport(player, DimensionalDoorsInitializer.getWorld(location.world), location.pos, 0);
|
return teleport(player, DimensionalDoorsInitializer.getWorld(location.world), location.pos, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleport(ServerPlayerEntity player, RotatedLocation location) {
|
public static ServerPlayerEntity teleport(ServerPlayerEntity player, RotatedLocation location) {
|
||||||
teleport(player, DimensionalDoorsInitializer.getWorld(location.world), location.pos, (int) location.yaw);
|
return teleport(player, DimensionalDoorsInitializer.getWorld(location.world), location.pos, (int) location.yaw);
|
||||||
}
|
}
|
||||||
|
public static <E extends Entity> E teleportRandom(E entity, World world, double y) {
|
||||||
public static void teleportRandom(Entity entity, World world, double y) {
|
|
||||||
double scale = ThreadLocalRandom.current().nextGaussian() * ThreadLocalRandom.current().nextInt(90);
|
double scale = ThreadLocalRandom.current().nextGaussian() * ThreadLocalRandom.current().nextInt(90);
|
||||||
teleport(
|
return teleport(
|
||||||
entity,
|
entity,
|
||||||
world,
|
world,
|
||||||
entity.getPos()
|
entity.getPos()
|
||||||
|
@ -71,9 +70,9 @@ public final class TeleportUtil {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleportUntargeted(Entity entity, World world) {
|
public static <E extends Entity> E teleportUntargeted(E entity, World world) {
|
||||||
double actualScale = entity.world.getDimension().getCoordinateScale() / world.getDimension().getCoordinateScale();
|
double actualScale = entity.world.getDimension().getCoordinateScale() / world.getDimension().getCoordinateScale();
|
||||||
teleport(
|
return teleport(
|
||||||
entity,
|
entity,
|
||||||
world,
|
world,
|
||||||
entity.getPos().multiply(actualScale, 1, actualScale),
|
entity.getPos().multiply(actualScale, 1, actualScale),
|
||||||
|
@ -81,9 +80,9 @@ public final class TeleportUtil {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void teleportUntargeted(Entity entity, World world, double y) {
|
public static <E extends Entity> E teleportUntargeted(E entity, World world, double y) {
|
||||||
double actualScale = entity.world.getDimension().getCoordinateScale() / world.getDimension().getCoordinateScale();
|
double actualScale = entity.world.getDimension().getCoordinateScale() / world.getDimension().getCoordinateScale();
|
||||||
teleport(
|
return teleport(
|
||||||
entity,
|
entity,
|
||||||
world,
|
world,
|
||||||
entity.getPos()
|
entity.getPos()
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package org.dimdev.dimdoors.util.math;
|
package org.dimdev.dimdoors.util.math;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@ -55,42 +52,40 @@ public interface Equation {
|
||||||
});
|
});
|
||||||
|
|
||||||
// some logic first
|
// some logic first
|
||||||
|
// ? :
|
||||||
|
parseRules.add(new SplitterParser()
|
||||||
|
.add((variableMap, equations) -> equations[0].asBoolean(variableMap) ? equations[1].apply((variableMap)) : equations[2].apply(variableMap), "?", ":"));
|
||||||
|
|
||||||
// ||
|
// ||
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> or = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
or.put("||", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) || second.asBoolean(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].asBoolean(variableMap) || equations[1].asBoolean((variableMap))), "||"));
|
||||||
parseRules.add(new SplitterParser(or));
|
|
||||||
|
|
||||||
// &&
|
// &&
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> and = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
and.put("&&", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) && second.asBoolean(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].asBoolean(variableMap) && equations[1].asBoolean((variableMap))), "&&"));
|
||||||
parseRules.add(new SplitterParser(and));
|
|
||||||
|
|
||||||
// ==, <=, >=, <, >
|
// ==, <=, >=, <, >
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> comparators = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
comparators.put("==", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) == second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].apply(variableMap) == equations[1].apply((variableMap))), "==")
|
||||||
comparators.put("<=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) <= second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].apply(variableMap) <= equations[1].apply((variableMap))), "<=")
|
||||||
comparators.put(">=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) >= second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].apply(variableMap) >= equations[1].apply((variableMap))), ">=")
|
||||||
comparators.put("<", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) < second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].apply(variableMap) < equations[1].apply((variableMap))), "<")
|
||||||
comparators.put(">", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) > second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> toDouble(equations[0].apply(variableMap) > equations[1].apply((variableMap))), ">"));
|
||||||
parseRules.add(new SplitterParser(comparators));
|
|
||||||
|
|
||||||
// +, -
|
// +, -
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap));
|
.add((variableMap, equations) -> equations[0].apply(variableMap) + equations[1].apply((variableMap)), "+")
|
||||||
sumOperations.put("-", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) - second.apply(stringDoubleMap));
|
.add((variableMap, equations) -> equations[0].apply(variableMap) - equations[1].apply((variableMap)), "-"));
|
||||||
parseRules.add(new SplitterParser(sumOperations));
|
|
||||||
|
|
||||||
// *, /, %
|
// *, /, %
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> dotOperations = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
dotOperations.put("*", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) * second.apply(stringDoubleMap));
|
.add((variableMap, equations) -> equations[0].apply(variableMap) * equations[1].apply((variableMap)), "*")
|
||||||
dotOperations.put("/", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) / second.apply(stringDoubleMap));
|
.add((variableMap, equations) -> equations[0].apply(variableMap) / equations[1].apply((variableMap)), "/")
|
||||||
dotOperations.put("%", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) % second.apply(stringDoubleMap));
|
.add((variableMap, equations) -> equations[0].apply(variableMap) % equations[1].apply((variableMap)), "%"));
|
||||||
parseRules.add(new SplitterParser(dotOperations));
|
|
||||||
|
|
||||||
// x^y
|
// x^y
|
||||||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> exponentOperations = new HashMap<>();
|
parseRules.add(new SplitterParser()
|
||||||
exponentOperations.put("^", (stringDoubleMap, first, second) -> Math.pow(first.apply(stringDoubleMap), second.apply(stringDoubleMap)));
|
.add((variableMap, equations) -> Math.pow(equations[0].apply(variableMap), equations[1].apply(variableMap)), "^"));
|
||||||
parseRules.add(new SplitterParser(exponentOperations));
|
|
||||||
|
|
||||||
// H with H(0) = 1: https://en.wikipedia.org/wiki/Heaviside_step_function
|
// H with H(0) = 1: https://en.wikipedia.org/wiki/Heaviside_step_function
|
||||||
parseRules.add(new FunctionParser("H", 1, 1, ((stringDoubleMap, equations) -> equations[0].apply(stringDoubleMap) >= 0 ? 1d : 0d)));
|
parseRules.add(new FunctionParser("H", 1, 1, ((stringDoubleMap, equations) -> equations[0].apply(stringDoubleMap) >= 0 ? 1d : 0d)));
|
||||||
|
@ -151,10 +146,17 @@ public interface Equation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SplitterParser implements EquationParser {
|
private static class SplitterParser implements EquationParser {
|
||||||
private final Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> operations;
|
private final Map<String, Pair<String[], BiFunction<Map<String, Double>, Equation[], Double>>> operations;
|
||||||
|
|
||||||
public SplitterParser(Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> operations) {
|
public SplitterParser() {
|
||||||
this.operations = operations;
|
this.operations = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SplitterParser add(BiFunction<Map<String, Double>, Equation[], Double> function, String... symbols) {
|
||||||
|
List<String> symbolList = Arrays.asList(symbols);
|
||||||
|
Collections.reverse(symbolList);
|
||||||
|
operations.put(symbolList.get(0), new Pair<>(symbolList.toArray(new String[0]), function));
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,12 +166,41 @@ public interface Equation {
|
||||||
String substring = toParse.substring(i);
|
String substring = toParse.substring(i);
|
||||||
if (substring.startsWith(")")) depth++;
|
if (substring.startsWith(")")) depth++;
|
||||||
else if (substring.startsWith("(")) depth--;
|
else if (substring.startsWith("(")) depth--;
|
||||||
for (String symbol : this.operations.keySet()) {
|
for (String currentSymbol : this.operations.keySet()) {
|
||||||
if (substring.startsWith(symbol) && depth == 0) {
|
if (depth == 0 && substring.startsWith(currentSymbol)) {
|
||||||
final TriFunction<Map<String, Double>, Equation, Equation, Double> operation = this.operations.get(symbol);
|
final Pair<String[], BiFunction<Map<String, Double>, Equation[], Double>> operation = this.operations.get(currentSymbol);
|
||||||
final Equation first = Equation.parse(toParse.substring(0, i));
|
final String[] symbols = operation.getLeft();
|
||||||
final Equation second = Equation.parse(toParse.substring(i + 1));
|
List<Pair<Integer, Integer>> partIndices = new ArrayList<>(symbols.length + 1);
|
||||||
return Optional.of(stringDoubleMap -> operation.apply(stringDoubleMap, first, second));
|
partIndices.add(new Pair<>(i + currentSymbol.length(), toParse.length()));
|
||||||
|
|
||||||
|
int symbolPointer = 1;
|
||||||
|
if (symbolPointer < symbols.length) currentSymbol = symbols[symbolPointer];
|
||||||
|
int endIndex = i;
|
||||||
|
int innerDepth = 0;
|
||||||
|
for (int j = i - 1; j >= 1 && symbolPointer < symbols.length; j--) {
|
||||||
|
String innerSubstring = toParse.substring(j);
|
||||||
|
|
||||||
|
if (innerSubstring.startsWith(")")) innerDepth++;
|
||||||
|
else if (innerSubstring.startsWith("(")) innerDepth--;
|
||||||
|
if (innerDepth == 0 && innerSubstring.startsWith(currentSymbol)) {
|
||||||
|
|
||||||
|
partIndices.add(new Pair<>(j + currentSymbol.length(), endIndex));
|
||||||
|
|
||||||
|
endIndex = j;
|
||||||
|
symbolPointer++;
|
||||||
|
if (symbolPointer < symbols.length) currentSymbol = symbols[symbolPointer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (symbolPointer < symbols.length) continue;
|
||||||
|
partIndices.add(new Pair<>(0, endIndex));
|
||||||
|
|
||||||
|
Equation[] equations = new Equation[partIndices.size()];
|
||||||
|
for (int j = 0; j < partIndices.size(); j++) {
|
||||||
|
Pair<Integer, Integer> pair = partIndices.get(j);
|
||||||
|
equations[partIndices.size() - j - 1] = Equation.parse(toParse.substring(pair.getLeft(), pair.getRight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(stringDoubleMap -> operation.getRight().apply(stringDoubleMap, equations));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.dimdev.dimdoors.util.math;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class EquationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parseAndApply() throws Equation.EquationParseException {
|
||||||
|
Map<String, Double> empty = new HashMap<>();
|
||||||
|
double expected;
|
||||||
|
String equation;
|
||||||
|
|
||||||
|
assertThrows(Equation.EquationParseException.class, () -> Equation.parse("."));
|
||||||
|
|
||||||
|
expected = 15d;
|
||||||
|
equation = Double.toString(expected);
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
|
||||||
|
|
||||||
|
expected = 4d;
|
||||||
|
equation = "2 + 2";
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
|
||||||
|
|
||||||
|
expected = 1;
|
||||||
|
equation = "1 ? 1 : 0";
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
|
||||||
|
expected = 0;
|
||||||
|
equation = "0 ? 1 : 0";
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
|
||||||
|
expected = 1;
|
||||||
|
equation = (Math.random() + 1d) + "? 1 : 0";
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
|
||||||
|
expected = 1;
|
||||||
|
equation = (Math.random() - 1d) + "? 1 : 0";
|
||||||
|
assertEquals(expected, Equation.parse(equation).apply(empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseAndAsBoolean() throws Equation.EquationParseException {
|
||||||
|
Map<String, Double> empty = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue