This commit is contained in:
Cilly Leang 2025-03-08 15:13:29 +11:00
parent 6c61b330d1
commit bc920a5d1e
Signed by: cilly
GPG key ID: 6500251E087653C9
15 changed files with 217 additions and 197 deletions

View file

@ -1,6 +1,7 @@
plugins {
id 'fabric-loom' version '1.10-SNAPSHOT'
id 'maven-publish'
id 'org.jetbrains.kotlin.jvm'
}
version = project.mod_version
@ -27,6 +28,7 @@ repositories {
includeGroup "maven.modrinth"
}
}
mavenCentral()
}
loom {
@ -38,6 +40,7 @@ dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc:fabric-language-kotlin:${project.kotlin_version}"
//modImplementation "maven.modrinth:linkart:5.4.5-1.20.6-build.29"
@ -63,8 +66,6 @@ java {
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
jar {
@ -92,3 +93,6 @@ publishing {
// retrieving dependencies.
}
}
kotlin {
jvmToolchain(21)
}

View file

@ -7,6 +7,7 @@ org.gradle.parallel=true
minecraft_version=1.21.4
yarn_mappings=1.21.4+build.8
loader_version=0.16.10
kotlin_version=1.13.1+kotlin.2.1.10
# Mod Properties
mod_version=1.0.0

View file

@ -7,4 +7,10 @@ pluginManagement {
mavenCentral()
gradlePluginPortal()
}
plugins {
id 'org.jetbrains.kotlin.jvm' version '2.1.10'
}
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
}

View file

@ -1,10 +1,9 @@
package moe.lava.cartloader.accessor
import net.minecraft.entity.vehicle.MinecartController
import net.minecraft.util.math.ChunkPos
import net.minecraft.world.World
import moe.lava.cartloader.impl.MixinAbstractMinecartEntityImpl
import net.minecraft.entity.vehicle.AbstractMinecartEntity
@Suppress("FunctionName")
interface AbstractMinecartEntityAccessor {
fun `cartloader$linkedTick`()
interface AccessorAbstractMinecartEntity {
fun `cartloader$getImpl`(): MixinAbstractMinecartEntityImpl
}

View file

@ -1,12 +1,7 @@
package moe.lava.cartloader.accessor
import net.minecraft.entity.vehicle.AbstractMinecartEntity
import net.minecraft.entity.vehicle.ExperimentalMinecartController
import net.minecraft.entity.vehicle.MinecartEntity
import net.minecraft.world.World
@Suppress("FunctionName")
interface ExperimentalMinecartControllerAccessor {
interface AccessorExperimentalMinecartController {
fun `cartloader$getSpeedMultiplers`(): Pair<Double, Double>
fun `cartloader$finishSlowdown`()
}

View file

@ -1,16 +1,17 @@
package moe.lava.cartloader.mixin.impl
package moe.lava.cartloader.impl
import moe.lava.cartloader.accessor.AbstractMinecartEntityAccessor
import moe.lava.cartloader.accessor.ExperimentalMinecartControllerAccessor
import moe.lava.cartloader.mixin.MixinAbstractMinecartEntity
import moe.lava.cartloader.accessor.AccessorAbstractMinecartEntity
import moe.lava.cartloader.accessor.AccessorExperimentalMinecartController
import net.minecraft.entity.Entity
import net.minecraft.entity.vehicle.AbstractMinecartEntity
import net.minecraft.entity.vehicle.MinecartController
import net.minecraft.server.world.ChunkTicketType
import net.minecraft.server.world.ServerWorld
import net.minecraft.util.math.ChunkPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.spongepowered.asm.mixin.injection.At
import org.spongepowered.asm.mixin.injection.Inject
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
import java.util.*
@ -18,24 +19,54 @@ import java.util.*
private val TICKET: ChunkTicketType<ChunkPos> =
ChunkTicketType.create("minecart", Comparator.comparingLong { obj: ChunkPos -> obj.toLong() }, 50)
class MixinAbstractMinecartEntityImpl(private val parent: AbstractMinecartEntityAccessor) {
class MixinAbstractMinecartEntityImpl(private val self: AbstractMinecartEntity) {
private val log: Logger = LoggerFactory.getLogger("cartloader@mixin.ame")
private var lastChunk: ChunkPos? = null
fun onTick() {
val world = parent.world;
// private var parent: UUID? = null;
// private var child: UUID? = null;
private var parent: AbstractMinecartEntity? = null;
private var child: AbstractMinecartEntity? = null;
var linked = false
private set
private var allowTicking = false;
private fun linkedTick() {
allowTicking = true;
self.tick();
}
fun linkTo(target: AbstractMinecartEntity) {
parent = target
linked = true
val impl = (target as AccessorAbstractMinecartEntity).`cartloader$getImpl`()
impl.child = self;
impl.linked = true;
}
fun onPreTick(world: World, chunkPos: ChunkPos, callbackInfo: CallbackInfo) {
if (linked && !allowTicking && parent != null) {
callbackInfo.cancel();
return;
}
allowTicking = false;
if (world !is ServerWorld) return
if (lastChunk == parent.chunkPos) return
lastChunk = parent.chunkPos
if (lastChunk == chunkPos) return
lastChunk = chunkPos
world.chunkManager.addTicket(TICKET, lastChunk, 3, lastChunk)
}
fun slowdown(cir: CallbackInfoReturnable<Vec3d>) {
val world = parent.world
val controller = parent.`cartloader$getController`()
fun onPostTick() {
if (child != null)
(child as AccessorAbstractMinecartEntity).`cartloader$getImpl`().linkedTick()
}
fun slowdown(world: World, controller: MinecartController, cir: CallbackInfoReturnable<Vec3d>) {
if (world !is ServerWorld) return
if (controller !is ExperimentalMinecartControllerAccessor) {
if (controller !is AccessorExperimentalMinecartController) {
return
}

View file

@ -1,13 +1,13 @@
package moe.lava.cartloader.mixin.impl
package moe.lava.cartloader.impl
import jdk.jfr.Experimental
import moe.lava.cartloader.accessor.ExperimentalMinecartControllerAccessor
import moe.lava.cartloader.mixin.MixinExperimentalMinecartController
import moe.lava.cartloader.accessor.AccessorExperimentalMinecartController
import net.minecraft.block.BlockState
import net.minecraft.block.Blocks
import net.minecraft.block.PoweredRailBlock
import net.minecraft.entity.vehicle.AbstractMinecartEntity
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import org.slf4j.LoggerFactory
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
@ -17,19 +17,19 @@ private const val MAX_ACCELERATION = TOTAL_ACCELERATION * (1 - ACCELERATION_DECA
private const val FINAL_ACCELERATION = TOTAL_ACCELERATION *
ACCELERATION_DECAY * ACCELERATION_DECAY * ACCELERATION_DECAY * ACCELERATION_DECAY * ACCELERATION_DECAY
class MixinExperimentalMinecartControllerImpl(private val parent: ExperimentalMinecartControllerAccessor) {
class MixinExperimentalMinecartControllerImpl(private val parent: AccessorExperimentalMinecartController) {
private val log = LoggerFactory.getLogger("cartloader@mixin.emc")
var currentMultiplier = 0.5
var targetMultiplier = 0.5
private var specialAcceleration = false
fun checkRail(pos: BlockPos, railState: BlockState) {
fun checkRail(world: World, pos: BlockPos, railState: BlockState) {
val unpoweredRail = railState.isOf(Blocks.POWERED_RAIL) && !railState.get(PoweredRailBlock.POWERED)
if (!railState.isOf(Blocks.DETECTOR_RAIL) && !unpoweredRail)
return
val under: BlockState = parent.world.getBlockState(pos.down())
val under: BlockState = world.getBlockState(pos.down())
var newMultiplier = 0.0
if (under.isOf(Blocks.IRON_BLOCK)) newMultiplier = 0.25
else if (under.isOf(Blocks.GOLD_BLOCK)) newMultiplier = 0.5
@ -51,6 +51,7 @@ class MixinExperimentalMinecartControllerImpl(private val parent: ExperimentalMi
private var currentAcceleration = 0.0
fun accelerateFromPoweredRail(
minecart: AbstractMinecartEntity,
velocity: Vec3d,
railPos: BlockPos,
railState: BlockState,
@ -70,7 +71,7 @@ class MixinExperimentalMinecartControllerImpl(private val parent: ExperimentalMi
if (velocity.length() > 0.01)
cir.returnValue = velocity.normalize().multiply(velocity.length() * (1 + currentAcceleration))
else {
val vec3d: Vec3d = this.parent.minecart.getLaunchDirection(railPos)
val vec3d: Vec3d = minecart.getLaunchDirection(railPos)
cir.returnValue = if (vec3d.lengthSquared() <= 0.0)
velocity
else
@ -89,8 +90,4 @@ class MixinExperimentalMinecartControllerImpl(private val parent: ExperimentalMi
cir.returnValue = velocity
}
}
var linked = true
private set;
}

View file

@ -1,4 +1,42 @@
package moe.lava.cartloader.impl
import moe.lava.cartloader.accessor.AccessorAbstractMinecartEntity
import net.minecraft.entity.Entity
import net.minecraft.entity.ItemEntity
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.vehicle.AbstractMinecartEntity
import net.minecraft.item.Items
import net.minecraft.util.ActionResult
import net.minecraft.util.Hand
class MixinPlayerEntityImpl {
private var linking: AbstractMinecartEntity? = null
fun interact(minecart: Entity, player: PlayerEntity, hand: Hand): ActionResult? {
if (minecart !is AbstractMinecartEntity)
return null
if (minecart !is AccessorAbstractMinecartEntity)
return null;
if (!player.getStackInHand(hand).isOf(Items.CHAIN))
return null
val target = linking
if (target == null) {
linking = minecart
return ActionResult.SUCCESS
}
if (target !is AccessorAbstractMinecartEntity)
return null
linking = null
if (!target.isAlive)
return ActionResult.FAIL
if (!minecart.boundingBox.expand(0.1).intersects(target.boundingBox))
return ActionResult.FAIL
target.`cartloader$getImpl`().linkTo(minecart)
return ActionResult.SUCCESS
}
}

View file

@ -1,82 +1,50 @@
package moe.lava.cartloader.mixin;
import moe.lava.cartloader.accessor.ExperimentalMinecartControllerAccessor;
import moe.lava.cartloader.accessor.AccessorAbstractMinecartEntity;
import moe.lava.cartloader.impl.MixinAbstractMinecartEntityImpl;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.MinecartController;
import net.minecraft.entity.vehicle.VehicleEntity;
import net.minecraft.server.world.ChunkTicketType;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Pair;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Comparator;
import java.util.Objects;
@Mixin(AbstractMinecartEntity.class)
public abstract class AbstractMinecartEntityMixin extends VehicleEntity {
public abstract class MixinAbstractMinecartEntity extends VehicleEntity implements AccessorAbstractMinecartEntity {
@Final
@Shadow
private MinecartController controller;
public AbstractMinecartEntityMixin(EntityType<?> entityType, World world) {
@Unique
private final MixinAbstractMinecartEntityImpl impl = new MixinAbstractMinecartEntityImpl((AbstractMinecartEntity) (Object) this);
@Unique
public @NotNull MixinAbstractMinecartEntityImpl cartloader$getImpl() {
return impl;
}
public MixinAbstractMinecartEntity(EntityType<?> entityType, World world) {
super(entityType, world);
}
@Unique
private ChunkPos lastChunk;
@Inject(at = @At("HEAD"), method = "tick", cancellable = true)
private void onPreTick(CallbackInfo info) {
impl.onPreTick(this.getWorld(), this.getChunkPos(), info);
}
@Unique
private static final Logger log = LoggerFactory.getLogger("cartloader@ameMixin");
@Unique
private static final ChunkTicketType<ChunkPos> TICKET = ChunkTicketType.create("minecart", Comparator.comparingLong(ChunkPos::toLong), 50);
@Inject(at = @At("HEAD"), method = "tick")
private void onTick(CallbackInfo info) {
if (!(getWorld() instanceof ServerWorld world))
return;
if (lastChunk == getChunkPos())
return;
lastChunk = getChunkPos();
world.getChunkManager().addTicket(TICKET, lastChunk, 3, lastChunk);
@Inject(at = @At("RETURN"), method = "tick")
private void onPostTick(CallbackInfo info) {
impl.onPostTick();
}
@Inject(method = "applySlowdown", at = @At(value = "RETURN"), cancellable = true)
private void cartloader$slowDown(Vec3d velocity, CallbackInfoReturnable<Vec3d> cir) {
if (!(this.getWorld() instanceof ServerWorld world))
return;
if (!(controller instanceof ExperimentalMinecartControllerAccessor mixedController)) {
return;
}
Pair<Double, Double> multiplers = mixedController.cartloader$getSpeedMultiplers();
if (Objects.equals(multiplers.getLeft(), multiplers.getRight()))
return;
double base = controller.getMaxSpeed(world);
double mult = multiplers.getRight() / multiplers.getLeft();
double newMax = base * mult;
Vec3d ret = cir.getReturnValue();
double diff = ret.horizontalLength() - newMax;
if (diff > 0) {
if (diff < 0.15)
mixedController.cartloader$finishSlowdown();
else
cir.setReturnValue(ret.multiply(0.95f));
}
impl.slowdown(this.getWorld(), this.controller, cir);
}
}

View file

@ -3,9 +3,7 @@ package moe.lava.cartloader.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Vec3d;
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;
@ -13,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugHud.class)
public class DebugHudMixin {
public class MixinDebugHud {
@Inject(at = @At("RETURN"), method = "getLeftText")
private void cartloader$addLeftText(CallbackInfoReturnable<List<String>> cir) {
Entity ent = MinecraftClient.getInstance().getCameraEntity();

View file

@ -1,4 +1,32 @@
package moe.lava.cartloader.mixin;
public class MixinEntity {
import moe.lava.cartloader.accessor.AccessorAbstractMinecartEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.util.math.Vec3d;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Entity.class)
public abstract class MixinEntity {
@Unique
private boolean checkLink(Entity e) {
if (e instanceof AccessorAbstractMinecartEntity minecart)
return minecart.cartloader$getImpl().getLinked();
return false;
}
@Inject(method = "pushAwayFrom", at = @At("HEAD"), cancellable = true)
private void cartloader$cancelCollision(Entity entity, CallbackInfo ci) {
Entity self = (Entity) (Object) this;
if (checkLink(self) || checkLink(entity))
ci.cancel();
}
@Inject(method = "adjustMovementForCollisions(Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/Vec3d;", at = @At("HEAD"), cancellable = true)
private void cartloader$cancelCollision(Vec3d movement, CallbackInfoReturnable<Vec3d> cir) {
}
}

View file

@ -1,52 +1,40 @@
package moe.lava.cartloader.mixin;
import moe.lava.cartloader.accessor.ExperimentalMinecartControllerAccessor;
import kotlin.Pair;
import moe.lava.cartloader.accessor.AccessorAbstractMinecartEntity;
import moe.lava.cartloader.accessor.AccessorExperimentalMinecartController;
import moe.lava.cartloader.impl.MixinExperimentalMinecartControllerImpl;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.PoweredRailBlock;
import net.minecraft.block.enums.RailShape;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.ExperimentalMinecartController;
import net.minecraft.entity.vehicle.MinecartController;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Pair;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jetbrains.annotations.NotNull;
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.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ExperimentalMinecartController.class)
public abstract class ExperimentalMinecartControllerMixin extends MinecartController implements ExperimentalMinecartControllerAccessor {
public abstract class MixinExperimentalMinecartController extends MinecartController implements AccessorExperimentalMinecartController {
@Unique
private static final Logger log = LoggerFactory.getLogger("cartloader@emcmixin");
private final MixinExperimentalMinecartControllerImpl impl = new MixinExperimentalMinecartControllerImpl(this);
@Unique
private double currentMultiplier = 0.5;
@Unique
private double targetMultiplier = 0.5;
@Unique
private boolean specialAcceleration = false;
protected ExperimentalMinecartControllerMixin(AbstractMinecartEntity minecart) {
protected MixinExperimentalMinecartController(AbstractMinecartEntity minecart) {
super(minecart);
}
@Unique
public Pair<Double, Double> cartloader$getSpeedMultiplers() {
//return this.speedMultiplier;
return new Pair<>(this.currentMultiplier, this.targetMultiplier);
public @NotNull Pair<Double, Double> cartloader$getSpeedMultiplers() {
return new Pair<>(impl.getCurrentMultiplier(), impl.getTargetMultiplier());
}
@Unique
public void cartloader$finishSlowdown() {
this.currentMultiplier = this.targetMultiplier;
impl.setCurrentMultiplier(impl.getTargetMultiplier());
}
@Inject(method = "calcNewHorizontalVelocity", at = @At("HEAD"))
@ -59,85 +47,30 @@ public abstract class ExperimentalMinecartControllerMixin extends MinecartContro
RailShape railShape,
CallbackInfoReturnable<Vec3d> cir
) {
if (!(railState.isOf(Blocks.DETECTOR_RAIL) || (railState.isOf(Blocks.POWERED_RAIL) && !railState.get(PoweredRailBlock.POWERED)))) {
return;
}
BlockState under = this.getWorld().getBlockState(pos.down());
double newMultiplier = 0;
if (under.isOf(Blocks.IRON_BLOCK))
newMultiplier = 0.25;
else if (under.isOf(Blocks.GOLD_BLOCK))
newMultiplier = 0.5;
else if (under.isOf(Blocks.EMERALD_BLOCK))
newMultiplier = 0.75;
else if (under.isOf(Blocks.DIAMOND_BLOCK))
newMultiplier = 1.0;
if (newMultiplier != 0) {
specialAcceleration = true;
targetMultiplier = newMultiplier;
}
if (targetMultiplier > currentMultiplier)
currentMultiplier = targetMultiplier;
impl.checkRail(world, pos, railState);
}
@Inject(method = "getMaxSpeed", at = @At(value = "RETURN"), cancellable = true)
private void cartloader$applyMaxSpeedMultiplier(ServerWorld world, CallbackInfoReturnable<Double> cir) {
double ret = cir.getReturnValue();
cir.setReturnValue(ret * currentMultiplier);
//cir.setReturnValue(ret * speedMultiplier);
impl.applyMaxSpeedMultiplier(cir);
}
@Unique
private static final double TOTAL_ACCELERATION = 0.075;
@Unique
private static final double ACCELERATION_DECAY = 0.5;
@Unique
private static final double MAX_ACCELERATION = TOTAL_ACCELERATION * (1 - ACCELERATION_DECAY);
@Unique
private static final double FINAL_ACCELERATION = TOTAL_ACCELERATION * Math.pow(ACCELERATION_DECAY, 5);
@Unique
private double currentAcceleration = 0.0;
@Inject(method = "accelerateFromPoweredRail", at = @At("HEAD"), cancellable = true)
private void accelerateFromPoweredRail(Vec3d velocity, BlockPos railPos, BlockState railState, CallbackInfoReturnable<Vec3d> cir) {
if (!specialAcceleration)
return;
if (railState.isOf(Blocks.POWERED_RAIL) && railState.get(PoweredRailBlock.POWERED))
currentAcceleration = MAX_ACCELERATION;
if (!railState.isOf(Blocks.POWERED_RAIL)) {
currentAcceleration = currentAcceleration * ACCELERATION_DECAY;
if (currentAcceleration <= FINAL_ACCELERATION)
currentAcceleration = 0.0;
}
//log.info(String.valueOf(currentAcceleration));
if (velocity.length() > 0.01)
cir.setReturnValue(velocity.normalize().multiply(velocity.length() * (1 + currentAcceleration)));
else {
Vec3d vec3d = this.minecart.getLaunchDirection(railPos);
cir.setReturnValue(vec3d.lengthSquared() <= 0.0 ? velocity : vec3d.multiply(velocity.length() + MAX_ACCELERATION));
}
private void cartloader$accelerateFromPoweredRail(Vec3d velocity, BlockPos railPos, BlockState railState, CallbackInfoReturnable<Vec3d> cir) {
impl.accelerateFromPoweredRail(this.minecart, velocity, railPos, railState, cir);
}
@Inject(method = "decelerateFromPoweredRail", at = @At("HEAD"), cancellable = true)
private void decelerateFromPoweredRail(Vec3d velocity, BlockState railState, CallbackInfoReturnable<Vec3d> cir) {
if (!specialAcceleration)
return;
private void cartloader$decelerateFromPoweredRail(Vec3d velocity, BlockState railState, CallbackInfoReturnable<Vec3d> cir) {
impl.decelerateFromPoweredRail(velocity, railState, cir);
}
if (railState.isOf(Blocks.POWERED_RAIL) && !(Boolean)railState.get(PoweredRailBlock.POWERED)) {
log.info("Decel");
log.info(String.valueOf(velocity.length()));
cir.setReturnValue(velocity.length() < 0.03 ? Vec3d.ZERO : velocity.multiply(0.915));
} else {
cir.setReturnValue(velocity);
}
//@Inject(method = "pushAwayFromEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;pushAwayFrom(Lnet/minecraft/entity/Entity;)V"), cancellable = true)
@SuppressWarnings("InvalidInjectorMethodSignature")
@ModifyConstant(method = "pushAwayFromEntities", constant = @Constant(classValue = AbstractMinecartEntity.class))
private boolean cartloader$handleCollision(Object obj, Class<?> c) {
if (((AccessorAbstractMinecartEntity)minecart).cartloader$getImpl().getLinked())
return false;
return obj instanceof AbstractMinecartEntity;
}
}

View file

@ -1,18 +1,37 @@
package moe.lava.cartloader.mixin;
import moe.lava.cartloader.impl.MixinPlayerEntityImpl;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(PlayerEntity.class)
public class PlayerEntityMixin {
public abstract class MixinPlayerEntity extends LivingEntity {
@Shadow public abstract void handleStatus(byte status);
protected MixinPlayerEntity(EntityType<? extends LivingEntity> entityType, World world) {
super(entityType, world);
}
@Unique
private final MixinPlayerEntityImpl impl = new MixinPlayerEntityImpl();
@Redirect(method = "interact", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;interact(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;"))
private ActionResult meth(Entity entity, PlayerEntity player, Hand hand) {
ActionResult res = impl.interact(entity, player, hand);
if (res != null)
return res;
return entity.interact(player, hand);
}
}

View file

@ -3,13 +3,15 @@
"package": "moe.lava.cartloader.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"AbstractMinecartEntityMixin",
"ExperimentalMinecartControllerMixin"
"MixinAbstractMinecartEntity",
"MixinEntity",
"MixinExperimentalMinecartController",
"MixinPlayerEntity"
],
"injectors": {
"defaultRequire": 1
},
"client": [
"DebugHudMixin"
"MixinDebugHud"
]
}

View file

@ -19,6 +19,7 @@
],
"depends": {
"fabricloader": ">=0.15",
"fabric-language-kotlin": ">=1.13.1+kotlin.2.1.10",
"minecraft": "~1.21.4",
"java": ">=21"
}