diff --git a/src/main/java/net/robofox/copperrails/mixin/NewMinecartBehaviorMixin.java b/src/main/java/net/robofox/copperrails/mixin/NewMinecartBehaviorMixin.java index 74a96ac..2049e40 100644 --- a/src/main/java/net/robofox/copperrails/mixin/NewMinecartBehaviorMixin.java +++ b/src/main/java/net/robofox/copperrails/mixin/NewMinecartBehaviorMixin.java @@ -6,11 +6,15 @@ import net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.PoweredRailBlock; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.RailShape; import net.minecraft.world.level.gamerules.GameRules; import net.minecraft.world.phys.Vec3; import net.robofox.copperrails.CopperRails; import net.robofox.copperrails.CopperRailsConfig; +import net.robofox.copperrails.block.ModBlocks; import net.robofox.copperrails.block.custom.GenericCopperRailBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -26,45 +30,59 @@ protected NewMinecartBehaviorMixin(AbstractMinecart minecart) { } @Unique - private boolean isPoweringRail(BlockState state, Block block) { - // This code is injected into the start of AbstractMinecartEntity.moveAlongTrack()V + private RailShape getRailShape(BlockState blockState, Property property) { + RailShape railShape = blockState.getValue(property); + if (blockState.is(ModBlocks.RAIL_CROSSING)) { + boolean isPowered = blockState.getValue(PoweredRailBlock.POWERED); + if (isPowered) { + switch (railShape) { + case NORTH_SOUTH: return RailShape.EAST_WEST; + case EAST_WEST: return RailShape.NORTH_SOUTH; + default: CopperRails.LOGGER.error("Crossing rail has invalid shape"); + } + } + } + return railShape; + } + + @SuppressWarnings("unchecked") + @Unique + private > T getValueMaybeRailShape(BlockState blockState, Property property) { + if (property.getValueClass() == RailShape.class) { + return (T) getRailShape(blockState, (Property) property); + } + return blockState.getValue(property); + } + + @Redirect(method = "moveAlongTrack", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;")) + public > T getMoveAlongTrackMixin(BlockState blockState, Property property) { + return getValueMaybeRailShape(blockState, property); + } + + @Unique + private boolean isPoweringRail(BlockState state, Object block) { if (block == Blocks.POWERED_RAIL) { Block unknownRail = state.getBlock(); - // We want to check if this is a powering rail return (unknownRail instanceof GenericCopperRailBlock || unknownRail == Blocks.POWERED_RAIL); } else { CopperRails.LOGGER.warn("isOf() Mixin called with something else than Blocks.POWERED_RAIL"); - return state.is(block); + return state.is((Block) block); } } - @Redirect( - method = "calculateHaltTrackSpeed", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")) - public boolean isPoweringRailHaltTrackSpeed(BlockState state, Block block) { + @Redirect(method = "calculateHaltTrackSpeed", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/block/state/BlockState;is(Ljava/lang/Object;)Z")) + public boolean isPoweringRailHaltTrackSpeed(BlockState state, Object block) { return isPoweringRail(state, block); } - @Redirect( - method = "calculateBoostTrackSpeed", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")) - public boolean isPoweringRailBoostTrackSpeed(BlockState state, Block block) { + @Redirect(method = "calculateBoostTrackSpeed", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/block/state/BlockState;is(Ljava/lang/Object;)Z")) + public boolean isPoweringRailBoostTrackSpeed(BlockState state, Object block) { return isPoweringRail(state, block); } -// @Inject( -// method = "calculateBoostTrackSpeed", -// at = @At( -// value = "INVOKE", -// target = "Lnet/minecraft/world/phys/Vec3;length()D", -// ordinal = 0) -// ) -// private void - @Unique public int getMaxRailSpeed(BlockState blockState) { Block block = blockState.getBlock(); @@ -73,20 +91,14 @@ public int getMaxRailSpeed(BlockState blockState) { CopperRails.LOGGER.error("Could not access to server gamerules ! Please report this bug"); return CopperRailsConfig.MAX_RAIL_SPEED_NOT_EXPERIMENTAL_BPS; } - GameRules gamerules = server.getWorldData().getGameRules(); + GameRules gamerules = server.getGameRules(); int maxSpeed = getMaxSpeedByRailType(block, gamerules); return Integer.min(maxSpeed, gamerules.get(GameRules.MAX_MINECART_SPEED)); } - @ModifyVariable( - method = "calculateBoostTrackSpeed", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/phys/Vec3;length()D", - ordinal = 0), - argsOnly = true) + @ModifyVariable(method = "calculateBoostTrackSpeed", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/phys/Vec3;length()D", ordinal = 0), argsOnly = true) private Vec3 slowedDownVec3(Vec3 vec3, @Local(ordinal = 0, argsOnly = true) BlockState blockState) { - // We already know that blockstate is a powered rail. float maxSpeed = getMaxRailSpeed(blockState) / 20.0F; if (vec3.length() > maxSpeed) { double d = Double.max(vec3.length() * 0.95 - 0.06, maxSpeed); @@ -94,7 +106,4 @@ private Vec3 slowedDownVec3(Vec3 vec3, @Local(ordinal = 0, argsOnly = true) Bloc } return vec3; } - - - -} \ No newline at end of file +}