diff --git a/CHANGELOG.md b/CHANGELOG.md index 7293489..c3119bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [4.1.0] - 2024-12-15 +- Add more configurable speeds via /gamerule + - minecartMaxSpeed: Generic max speed for all carts unless overridden + - minecartMaxSpeedPlayerRider: If not 0, overrides speed only for player ridden carts + - minecartMaxSpeedOtherRider: If not 0, overrides speed only for non-player ridden carts + - minecartMaxSpeedEmptyRider: If not 0, overrides speed only for rideable carts that are empty +- (Removed gamerule aceCartSpeed) + ## [4.0.0] - 2024-12-15 - Rebase mod on improved minecarts experiment - The experimental code will be activated for all carts diff --git a/gradle.properties b/gradle.properties index 5e8115b..a5f75d1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,6 +9,6 @@ loader_version=0.16.9 fabric_api_version=0.112.0+1.21.3 # Mod Properties -mod_version = 4.0.0 +mod_version = 4.1.0 maven_group = audaki.minecraft archives_base_name = ACE diff --git a/src/main/java/audaki/cart_engine/AceGameRules.java b/src/main/java/audaki/cart_engine/AceGameRules.java index 940fe00..e8e8d66 100644 --- a/src/main/java/audaki/cart_engine/AceGameRules.java +++ b/src/main/java/audaki/cart_engine/AceGameRules.java @@ -5,11 +5,20 @@ import net.minecraft.world.level.GameRules; public class AceGameRules { - public static GameRules.Key ACE_CART_SPEED; + // All speeds in blocks per second + public static GameRules.Key MINECART_MAX_SPEED_PLAYER_RIDER; + public static GameRules.Key MINECART_MAX_SPEED_OTHER_RIDER; + public static GameRules.Key MINECART_MAX_SPEED_EMPTY_RIDER; public static void register() { - ACE_CART_SPEED = GameRuleRegistry.register("aceCartSpeed", + MINECART_MAX_SPEED_PLAYER_RIDER = GameRuleRegistry.register("minecartMaxSpeedPlayerRider", GameRules.Category.PLAYER, GameRuleFactory.createIntRule(20)); + MINECART_MAX_SPEED_OTHER_RIDER = GameRuleRegistry.register("minecartMaxSpeedOtherRider", + GameRules.Category.PLAYER, + GameRuleFactory.createIntRule(0)); + MINECART_MAX_SPEED_EMPTY_RIDER = GameRuleRegistry.register("minecartMaxSpeedEmptyRider", + GameRules.Category.PLAYER, + GameRuleFactory.createIntRule(0)); } } diff --git a/src/main/java/audaki/cart_engine/mixin/NewMinecartBehaviorMixin.java b/src/main/java/audaki/cart_engine/mixin/NewMinecartBehaviorMixin.java index 50df033..b0e2b1d 100644 --- a/src/main/java/audaki/cart_engine/mixin/NewMinecartBehaviorMixin.java +++ b/src/main/java/audaki/cart_engine/mixin/NewMinecartBehaviorMixin.java @@ -2,14 +2,22 @@ import audaki.cart_engine.AceGameRules; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.vehicle.AbstractMinecart; import net.minecraft.world.entity.vehicle.MinecartBehavior; import net.minecraft.world.entity.vehicle.NewMinecartBehavior; +import net.minecraft.world.level.GameRules; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.function.Consumer; +import java.util.function.IntConsumer; + @Mixin(NewMinecartBehavior.class) public abstract class NewMinecartBehaviorMixin extends MinecartBehavior { @@ -19,10 +27,29 @@ protected NewMinecartBehaviorMixin(AbstractMinecart abstractMinecart) { @Inject(at = @At("HEAD"), method = "getMaxSpeed", cancellable = true) public void _getMaxSpeed(ServerLevel level, CallbackInfoReturnable cir) { - if (minecart.isRideable()) { - int speedBlocksPerSecond = level.getGameRules().getInt(AceGameRules.ACE_CART_SPEED); - cir.setReturnValue(speedBlocksPerSecond * (this.minecart.isInWater() ? 0.5 : 1.0) / 20.0); + if (!minecart.isRideable()) { + return; + } + + IntConsumer setSpeed = (speed) -> { + if (speed == 0) { + return; + } + cir.setReturnValue(speed * (this.minecart.isInWater() ? 0.5 : 1.0) / 20.0); cir.cancel(); + }; + + Entity passenger = minecart.getFirstPassenger(); + if (passenger == null) { + setSpeed.accept(level.getGameRules().getInt(AceGameRules.MINECART_MAX_SPEED_EMPTY_RIDER)); + return; } + + if (passenger instanceof Player) { + setSpeed.accept(level.getGameRules().getInt(AceGameRules.MINECART_MAX_SPEED_PLAYER_RIDER)); + return; + } + + setSpeed.accept(level.getGameRules().getInt(AceGameRules.MINECART_MAX_SPEED_OTHER_RIDER)); } }