diff --git a/README.md b/README.md index cc21abe..66fb436 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Speed Carts This mod adds the ability to control minecarts with signs. + +All you need to do is place a sign beside the rail, and put a number on the first line of the sign that indicates the desired speed of carts, in meters per second. diff --git a/build.gradle b/build.gradle index f807b77..7c8b1e3 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,14 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. - // You may need to force-disable transitiveness on them. + // Jackson API for config file parsing. + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.12.4' + include group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.12.4' + // Include Jackson dependencies since include directive is not transitive: + include group: 'org.yaml', name: 'snakeyaml', version: '1.27' + include group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.4' + include group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.4' + include group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.4' } processResources { diff --git a/gradle.properties b/gradle.properties index 1944b81..c01b156 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.11.6 # Mod Properties - mod_version = 1.0.0 + mod_version = 1.1.0 maven_group = nl.andrewlalis archives_base_name = speed-carts diff --git a/src/main/java/nl/andrewlalis/speed_carts/Config.java b/src/main/java/nl/andrewlalis/speed_carts/Config.java new file mode 100644 index 0000000..972403c --- /dev/null +++ b/src/main/java/nl/andrewlalis/speed_carts/Config.java @@ -0,0 +1,65 @@ +package nl.andrewlalis.speed_carts; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Contains all configuration options and the logic for loading config. + */ +public class Config { + private static final Path CONFIG_FILE = Path.of("config", "speed_carts.yaml"); + + private final double defaultSpeed; + private final double minimumSpeed; + private final double maximumSpeed; + private final String signRegex; + + public Config() { + try { + this.ensureConfigExists(); + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + JsonNode configJson = mapper.readTree(Files.newInputStream(CONFIG_FILE)); + this.defaultSpeed = configJson.get("defaultSpeed").asDouble(); + this.minimumSpeed = configJson.get("minimumSpeed").asDouble(); + this.maximumSpeed = configJson.get("maximumSpeed").asDouble(); + this.signRegex = configJson.get("signRegex").asText(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private void ensureConfigExists() throws IOException { + if (!Files.exists(CONFIG_FILE)) { + var out = Files.newOutputStream(CONFIG_FILE); + var defaultConfigInputStream = SpeedCarts.class.getClassLoader().getResourceAsStream("default_config.yaml"); + if (defaultConfigInputStream == null) { + throw new IOException("Could not load default_config.yaml"); + } + defaultConfigInputStream.transferTo(out); + defaultConfigInputStream.close(); + out.close(); + } + } + + public double getDefaultSpeed() { + return defaultSpeed; + } + + public double getMinimumSpeed() { + return minimumSpeed; + } + + public double getMaximumSpeed() { + return maximumSpeed; + } + + public String getSignRegex() { + return signRegex; + } +} diff --git a/src/main/java/nl/andrewlalis/speed_carts/SpeedCarts.java b/src/main/java/nl/andrewlalis/speed_carts/SpeedCarts.java index d7b354a..8eced88 100644 --- a/src/main/java/nl/andrewlalis/speed_carts/SpeedCarts.java +++ b/src/main/java/nl/andrewlalis/speed_carts/SpeedCarts.java @@ -3,8 +3,11 @@ package nl.andrewlalis.speed_carts; import net.fabricmc.api.ModInitializer; public class SpeedCarts implements ModInitializer { + public static Config config; + @Override public void onInitialize() { + config = new Config(); System.out.println("Speed Carts initialized."); } } diff --git a/src/main/java/nl/andrewlalis/speed_carts/mixin/AbstractMinecartMixin.java b/src/main/java/nl/andrewlalis/speed_carts/mixin/AbstractMinecartMixin.java index b02faf9..203243c 100644 --- a/src/main/java/nl/andrewlalis/speed_carts/mixin/AbstractMinecartMixin.java +++ b/src/main/java/nl/andrewlalis/speed_carts/mixin/AbstractMinecartMixin.java @@ -19,6 +19,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; +import nl.andrewlalis.speed_carts.SpeedCarts; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -29,6 +30,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.regex.Pattern; /** * Mixin which overrides the default minecart behavior so that we can define a @@ -36,9 +38,16 @@ import java.util.List; */ @Mixin(AbstractMinecartEntity.class) public abstract class AbstractMinecartMixin extends Entity { - private static final double DEFAULT_SPEED = 8.0; - private static final double MIN_SPEED = 1.0; - private static final double MAX_SPEED = 128.0; + private static final double DEFAULT_SPEED = SpeedCarts.config.getDefaultSpeed(); + private static final double MIN_SPEED = SpeedCarts.config.getMinimumSpeed(); + private static final double MAX_SPEED = SpeedCarts.config.getMaximumSpeed(); + private static final Pattern SIGN_PATTERN = Pattern.compile(SpeedCarts.config.getSignRegex()); + + /** + * Time in game ticks, to wait before attempting to update the cart's speed + * from the same position, after that block/sign has already updated the + * cart's speed just before. + */ private static final long SPEED_UPDATE_COOLDOWN = 20 * 3; /** @@ -130,6 +139,9 @@ public abstract class AbstractMinecartMixin extends Entity { private boolean updateSpeedForSign(SignBlockEntity sign) { Text text = sign.getTextOnRow(0, false); String s = text.asString(); + if (!SIGN_PATTERN.matcher(s).matches()) { + return false; + } try { double speed = Double.parseDouble(s); if (speed >= MIN_SPEED && speed <= MAX_SPEED) { diff --git a/src/main/resources/default_config.yaml b/src/main/resources/default_config.yaml new file mode 100644 index 0000000..bfc745a --- /dev/null +++ b/src/main/resources/default_config.yaml @@ -0,0 +1,17 @@ +# Configuration for Speed Carts +# ----------------------------- +# A server restart is required to apply changes. + +# The default speed for all carts in the world, in meters per second. +defaultSpeed: 8 + +# The minimum allowable speed limit that can be set, in meters per second. +minimumSpeed: 1 + +# The maximum allowable speed limit that can be set, in meters per second. +# Note: when a player is riding the cart, it cannot exceed 32 m/s regardless of the maximum set here. +maximumSpeed: 128 + +# The regular expression that's used to determine if a sign should affect the cart's speed. +# By default, it matches any positive decimal number. +signRegex: \d+(\.\d+)? \ No newline at end of file